[算法/数学]拓展欧几里得算法(EXGCD)详细推导及应用
使用场景:
- 求 \(ax+by=c\) 的一个特解。
- 求 \(ax \equiv b \ (\text{mod} \ m)\) 的一个特解。
这两个实际上是一个问题。
公式推导
- 首先解决 \(ax+by=gcd(a,b)\) 的特解。
引入两个方程,我们通过 \(x_2,y_2\) 求 \(x_1,y_1\) ,因此问题可以无限细分 。
\[ \left\{\begin{matrix}
ax_1+by_1=gcd(a,b) \\
bx_2+(a \ \text{mod} \ b)y_2 = gcd(b,a \ \text{mod} \ b)
\end{matrix}\right.
\]
\[\because gcd(a,b)=gcd(b,a \ \text{mod} \ b)
\\
\therefore ax_1+by_1 = bx_2+(a \ \text{mod} \ b)y_2
\]
\[\because a\ \text{mod}\ b = a - \left \lfloor \frac{a}{b} \right \rfloor*b
\\
\therefore ax_1+by_1 = bx_2+(a - \left \lfloor \frac{a}{b} \right \rfloor*b )y_2
\]
\[ax_1+by_1 = bx_2+ay_2 - \left \lfloor \frac{a}{b} \right \rfloor*b y_2
\]
\[ax_1+by_1 = ay_2 + b(x_2- \left \lfloor \frac{a}{b} \right \rfloor * y_2)
\]
\[\left\{\begin{matrix}
x_1=y_2 \\
y_1=x_2- \left \lfloor \frac{a}{b} \right \rfloor * y_2
\end{matrix}\right.
\]
此时我们已经通过 \(x_2,y_2\) 求得 \(x_1,y_1\) ,那么 \(x_2,y_2\) 可以继续通过 \(x_3,y_3\) 求得,以此类推。
根据欧几里得算法求GCD原理,问题一定可以被简化为:
\[b=0
\\
\therefore a*x + 0*y = gcd (a,0)
\\
\therefore ax=a
\\
\therefore x=1,y\in R
\]
注意此处 \(y\in R\) ,而不是网络上大多数文章所说的 \(y=0\) ,也就是y在编码中实际上可以取任意值,只不过习惯上令 \(y=0\) 。
- 接下来通过 \(ax'+by'=gcd(a,b)\) 求 \(ax+by=c\) 。
\[\because ax'+by'=gcd(a,b)
\\
\therefore ax'*\frac{c}{gcd(a,b)}+by'*\frac{c}{gcd(a,b)}=c
\]
\[\therefore
\left\{\begin{matrix}
x= x'*\frac{c}{gcd(a,b)} \\
y= y'*\frac{c}{gcd(a,b)}
\end{matrix}\right.
\]
代码实现
- C++
int Exgcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
int d = Exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - (a / b) * y;
return d;
}
- Python
def Exgcd(a, b):
if b == 0:
return a, 1, 0
d, x, y = Exgcd(b, a % b)
return d, y, x - (a // b) * y

浙公网安备 33010602011771号