Tips
- 本文中所有
方程有解
均为方程有整数解
gcd
令
gcd
(
a
,
b
)
\gcd\left(a,b\right)
gcd(a,b)为
a
,
b
a,b
a,b的最大公约数。
那么
gcd
(
a
,
b
)
=
b
,
a
m
o
d
b
=
0
gcd
(
b
m
o
d
a
,
b
)
,
b
m
o
d
a
≠
0
\gcd(a,b)=\\ b,\ a\mod b=0\\ \gcd(b\mod a, b ),\ b\mod a \not= 0
gcd(a,b)=b, amodb=0gcd(bmoda,b), bmoda=0
或者是
gcd
(
a
,
b
)
=
b
,
a
=
0
gcd
(
b
m
o
d
a
,
b
)
,
a
≠
0
\gcd(a,b)=\\ b,\ a=0\\ \gcd(b\mod a, b ),\ a \not= 0
gcd(a,b)=b, a=0gcd(bmoda,b), a=0
算法复杂度
Θ
(
log
2
max
(
a
,
b
)
)
\Theta\left(\log_2\max\left(a,b\right)\right)
Θ(log2max(a,b))
exgcd
前置芝士
关于
x
,
y
x,y
x,y的一个二元一次方程
a
x
+
b
y
=
c
ax+by=c
ax+by=c
当且仅当
gcd
(
a
,
b
)
∣
c
\gcd\left(a,b\right)|c
gcd(a,b)∣c时,方程有解。
这是裴蜀定理,证明因为不会所以就不讲了
exgcd求逆元
我们有一个方程关于
x
,
y
x,y
x,y的一个二元一次方程
a
x
+
b
y
=
c
ax+by=c
ax+by=c
要使这个方程有解,则
gcd
(
a
,
b
)
∣
c
\gcd\left(a,b\right)|c
gcd(a,b)∣c。令
c
=
k
gcd
(
a
,
b
)
c=k\gcd(a,b)
c=kgcd(a,b),那么设一个关于
x
0
,
y
0
x_0,y_0
x0,y0的方程
a
0
x
0
+
b
0
y
0
=
gcd
(
a
0
,
b
0
)
a_0x_0+b_0y_0=\gcd(a_0,b_0)
a0x0+b0y0=gcd(a0,b0),那么
x
=
k
x
0
,
y
=
k
y
0
x=kx_0,y=ky_0
x=kx0,y=ky0
设这个方程有一组解
x
,
y
x,y
x,y,就不难得出这组方程的通解:
x
+
k
(
b
÷
gcd
(
a
,
b
)
)
,
y
−
k
(
a
÷
gcd
(
a
,
b
)
)
x+k(b\div\gcd(a,b)),y-k(a\div\gcd(a,b))
x+k(b÷gcd(a,b)),y−k(a÷gcd(a,b))(
k
k
k是整数)
只要求出一个解就可以求出所有解了。那么,我们怎么求助一组解呢?用exgcd(逆元)就可以了。
设这个二元一次方程是
a
0
x
0
+
b
0
y
0
=
gcd
(
a
0
,
b
0
)
a_0x_0+b_0y_0=\gcd(a_0,b_0)
a0x0+b0y0=gcd(a0,b0)然后通过一次exgcd后成为了
a
1
x
1
+
b
1
y
1
=
gcd
(
a
1
,
b
1
)
a_1x_1+b_1y_1=\gcd(a_1,b_1)
a1x1+b1y1=gcd(a1,b1),其中
a
1
=
b
0
,
b
1
=
b
0
m
o
d
a
0
,
gcd
(
a
0
,
b
0
)
=
gcd
(
a
1
,
b
1
)
a_1=b_0\ ,\ b_1=b_0\mod a_0,\gcd(a_0,b_0)=\gcd(a_1,b_1)
a1=b0 , b1=b0moda0,gcd(a0,b0)=gcd(a1,b1)(其实就是进行一次
gcd
\gcd
gcd辗转相除)
那么我们就可以得到
a
0
x
0
+
b
0
y
0
=
a
1
x
1
+
b
1
y
1
a_0x_0+b_0y_0=a_1x_1+b_1y_1
a0x0+b0y0=a1x1+b1y1
进而得到
y
0
=
x
1
,
x
0
=
y
1
−
⌊
b
0
/
a
0
⌋
×
x
1
y_0=x_1,x_0=y_1-⌊b_0/a_0⌋\times x_1
y0=x1,x0=y1−⌊b0/a0⌋×x1
当
a
1
=
0
a_1=0
a1=0的时候,令
x
0
=
0
,
y
0
=
1
x_0=0,y_0=1
x0=0,y0=1,这样就可以递归回溯了。