扩展欧几里得
B e ˊ z o u t B\acute{e}zout Beˊzout定理
对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。
它的一个重要推论是:a,b互质的充分必要条件是存在整数x, y使ax+by=1.
(以上内容来自百度)
证明:
- 我们知道在欧几里得算发的最后一步,即 b = 0 时,显然有 x = 1, y = 0,满足ax+by = gcd(a, b) = gcd(a, 0) = a。
- b > 0 时,根据欧几里得算法我们知道 :
g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a, b) = gcd(b, a mod b) gcd(a,b)=gcd(b,amodb)
我们假设存在一对整数 x, y。满足:
b x + ( a m o d b ) y = g c d ( b , a m o d b ) = g c d ( a , b ) bx + (a mod \, b)y = gcd(b, a mod b) = gcd(a, b) bx+(amodb)y=gcd(b,amodb)=gcd(a,b)
又因为 :
b x + ( a m o d b ) y = b x + ( a − b ⌊ a b ⌋ ) y = a y + b ( x − ⌊ a b ⌋ y ) bx + (a mod \, b)y = bx + \Big(a - b\lfloor \frac{a}{b} \rfloor\Big)y = ay + b\Big(x - \lfloor\frac{a}{b}\rfloor y\Big) bx+(amodb)y=bx+(a−b⌊ba⌋)y=ay+b(x−⌊ba⌋y)
所以令:
x ′ = y , y ′ = x − ⌊ a b ⌋ y x' = y, \quad y' = x - \lfloor \frac{a}{b} \rfloor y x′=y,y′=x−⌊ba⌋y
就可以得到:
a x ′ + b y ′ = g c d ( a , b ) ax' + by' = gcd(a, b) ax′+by′=gcd(a,b)
而且这里的 x’ 和 y’ 一定是整数。所以我们可以由此得到在欧几里得算法的最后一步结束后,我们可以用回溯法一步一步地向上得到整数x, y,使它们满足ax + by = gcd(a, b) 的关系。
证毕。
int exgcd(int a, int b, int &x, int &y){
if(b == 0){
x = 1; y = 0;
return a;
}
int d = exgcd(b, a % b, x, y);
int z = x; x = y; y = z - (a / b) * y;
return d;
}
用上述代码就可以求出方程 ax + by = d = gcd(x, y) 的一组特殊解
x
0
,
y
0
x_0, y_0
x0,y0。而对于更一般的方程 ax + by = c。这个方程当且仅当
d
∣
c
d\mid c
d∣c 时有解。我们就可以先求出ax + by = d 的特解
x
0
,
y
0
x_0, y_0
x0,y0。然后等式两边同时成上
c
d
\frac{c}{d}
dc,就得到了
a
x
0
c
d
+
b
y
0
c
d
=
d
c
d
ax_0\frac{c}{d} + by_0 \frac{c}{d} = d\frac{c}{d}
ax0dc+by0dc=ddc。也就是:
a
×
c
d
x
0
+
b
×
c
d
y
0
=
c
a \times\frac{c}{d}x_0 + b\times \frac{c}{d}y_0 = c
a×dcx0+b×dcy0=c
然后我们就得到了ax + by = c 的一组特解 :
c
d
x
0
,
c
d
y
0
\frac{c}{d}x_0 ,\; \frac{c}{d}y_0
dcx0,dcy0。
事实上我们可以通过数学推导构造出ax + by = c 的通解和
x
0
,
y
0
x_0, y_0
x0,y0的关系:
a
x
+
b
y
=
c
=
c
(
a
x
0
+
b
y
0
)
a
x
0
+
b
y
0
=
a
c
x
0
+
b
c
y
0
+
k
a
b
−
k
a
b
a
x
0
+
b
y
0
ax + by = c = \frac{c(ax_0 + by_0)}{ax_0 + by_0} = \frac{acx_0 + bcy_0 + kab - kab}{ax_0+by_0}
ax+by=c=ax0+by0c(ax0+by0)=ax0+by0acx0+bcy0+kab−kab
=
a
(
c
x
0
+
k
b
)
+
b
(
c
y
0
+
k
a
)
a
x
0
+
b
y
0
=
a
c
x
0
+
k
b
a
x
0
+
b
y
0
+
b
c
y
0
−
k
a
a
x
0
+
b
y
0
= \frac{a(cx_0+kb) + b(cy_0+ka)}{ax_0+by_0} = a \frac{cx_0+kb}{ax_0+by_0} + b\frac{cy_0-ka}{ax_0+by_0}
=ax0+by0a(cx0+kb)+b(cy0+ka)=aax0+by0cx0+kb+bax0+by0cy0−ka
又因为
a
x
0
+
b
y
0
=
d
ax_0 + by_0 = d
ax0+by0=d,所以:
a
x
+
b
y
=
c
=
a
c
x
0
+
k
b
d
+
b
c
y
0
−
k
a
d
=
a
(
c
d
x
0
+
b
d
k
)
+
b
(
c
d
y
0
+
a
d
k
)
ax + by = c = a\frac{cx_0 + kb}{d} + b\frac{cy_0-ka}{d} = a \Big(\frac{c}{d}x_0 + \frac{b}{d}k\Big) + b\Big( \frac{c}{d}y_0 + \frac{a}{d}k \Big)
ax+by=c=adcx0+kb+bdcy0−ka=a(dcx0+dbk)+b(dcy0+dak)
我们另:
x
=
c
d
x
0
+
b
d
k
,
y
=
c
d
y
0
+
a
d
k
x = \frac{c}{d}x_0 + \frac{b}{d}k,y = \frac{c}{d}y_0 + \frac{a}{d}k
x=dcx0+dbk,y=dcy0+dak
这就是 ax + by = c的通解了。(其中 k 取遍整数集)
参考文章:《算法竞赛进阶指南》