扩展欧几里得求形如
ax+by=c 的方程。
ax≡b(modm)⟺ax+my=b
-
对于不为
0 的整数
a,b,存在整数
x,y,使得
ax+by=gcd(a,b)。
-
方程
ax+by=c 有解,当且仅当
gcd(a,b)∣c。
特殊情况:对于
ax+by=gcd(a,b),当
b=0 时,令
x=1,y=0 即求得一组解。
一般情况:借鉴辗转相除法
gcd(a,b)=gcd(b,amodb),假设已经求得了
(bmoda)x0+ay0=gcd(a,b) 的一组解
(x0,y0),方程可以根据
amodm=a−m⌊ma⌋ 变形为
(b−a⌊ab⌋)x0+ay0=gcd(a,b)
⌊ab⌋x0+ay0+bx0=gcd(a,b)
a(y0−⌊ab⌋x0)+bx0=gcd(a,b)
交换
x0 与
y0
a(x0−⌊ab⌋y0)+by0=gcd(a,b)
{ax+by=gcd(a,b)a(x0−⌊ab⌋y0)+by0=gcd(a,b)⟺{x=x0−y0⌊ab⌋y=y0
int exgcd(int a, int b, int &x, int &y) {
if (a == 0) {
x = 0, y = 1;
return b;
}
int d = exgcd(b % a, a, y, x);
x -= b / a * y;
return d;
}
如何求最小正整数解。假设我们求出了
ax0+by0=gcd(a,b)
的一组解
(x0,y0)。有解的必要条件为
gcd(a,b)∣c,所以令
k=gcd(a,b)c。
ax+by=c
ax+by=k×gcd(a,b)
{akx+bky=gcd(a,b)ax0+by0=gcd(a,b)⟺{x=k×x0y=k×y0⟺{x=gcd(a,b)c×x0y=gcd(a,b)c×y0
a×gcd(a,b)c×x0+b×gcd(a,b)c×y0=c
为了求最小整数解,需要把上式的
x0 尽可能地减小,如果
x0 减小,对应的
y0 会增加。所以设
x0 减小了
t0,
y0 增加了
t1。
{x=x0×gcd(a,b)c−gcd(a,b)c×t0y=y0×gcd(a,b)c+gcd(a,b)c×t1⇓a×x0×gcd(a,b)c−a×gcd(a,b)c×t0+b×y0×gcd(a,b)c+b×gcd(a,b)c×t1=c∵a×gcd(a,b)c×x0+b×gcd(a,b)c×y0=c∴a×gcd(a,b)c×t0=b×gcd(a,b)c×t1t1t0=a×gcd(a,b)cb×gcd(a,b)ct1t0=ab
a(x0−t0)+b(y0+t1)=c⟺a(x0−t0)+b(y0+ba×t0)
让
t0=gcd(a,b)b,将
x0 减到不能再减为止,并考虑
gcd(a,b)b<0 的情况需要加上模数再取模。总结公式为
{xmin=(x0modgcd(a,b)b+gcd(a,b)b)modgcd(a,b)bymin=bc–a×x0