我在很久很久以前写过这篇文章但是因为自己特别菜当时不会 LaTeX \LaTeX LATEX,而且一些地方理解不够深入现在来做一下简单修改
扩展欧几里得算法(
e
x
g
c
d
exgcd
exgcd)可以用来求下面这个关于
x
,
y
x,y
x,y的不定方程的最小整数解
a
x
+
b
y
=
gcd
(
a
,
b
)
ax+by=\gcd(a,b)
ax+by=gcd(a,b)
我们回忆一下,我们之前使用辗转相除法求
gcd
\gcd
gcd的过程
当我们辗转到
b
0
=
0
b_0=0
b0=0的时候,那么这个时候的
a
0
=
gcd
(
a
,
b
)
a_0=\gcd(a,b)
a0=gcd(a,b)
那么由于满足
a
0
x
0
+
b
0
y
0
=
gcd
(
a
,
b
)
a_0x_0+b_0y_0=\gcd(a,b)
a0x0+b0y0=gcd(a,b)
显然
x
0
=
1
,
y
0
=
0
x_0=1,y_0=0
x0=1,y0=0
那么初值我们就可以确定了
接下来考虑回溯的时候如何更新
x
,
y
x,y
x,y
根据迭代的方法,我们应该有一个等式
a
2
x
2
+
b
2
y
2
=
a
1
x
1
+
b
1
y
1
=
gcd
(
a
,
b
)
a
2
x
2
+
b
2
y
2
=
b
2
x
1
+
(
a
2
m
o
d
b
2
)
y
1
a
2
x
2
+
b
2
y
2
=
b
2
x
1
+
(
a
2
−
⌊
a
2
b
2
⌋
b
2
)
y
1
a
2
x
2
+
b
2
y
2
=
b
2
x
1
+
a
2
y
1
−
⌊
a
2
b
2
⌋
b
2
y
1
(
x
2
−
y
1
)
a
2
+
(
y
2
−
x
1
+
⌊
a
2
b
2
⌋
y
1
)
b
2
=
0
∵
a
2
,
b
2
≠
0
∴
x
2
−
y
1
=
0
,
y
2
−
x
1
+
⌊
a
2
b
2
⌋
y
1
=
0
∴
x
2
=
y
1
,
y
2
=
x
1
−
⌊
a
2
b
2
⌋
y
1
\begin{aligned} a_2x_2+b_2y_2&=a_1x_1+b_1y_1=\gcd(a,b) \\ a_2x_2+b_2y_2&=b_2x_1+(a_2\bmod b_2)y_1 \\ a_2x_2+b_2y_2&=b_2x_1+(a_2-\lfloor\frac{a_2}{b_2}\rfloor b_2)y_1 \\ a_2x_2+b_2y_2&=b_2x_1+a_2y_1-\lfloor\frac{a_2}{b_2}\rfloor b_2y_1 \\ (x_2-y_1)a_2&+(y_2-x_1+\lfloor\frac{a_2}{b_2}\rfloor y_1)b_2=0\\ \because a_2,b_2&\neq 0 \\ \therefore x_2-y_1=0,&y_2-x_1+\lfloor\frac{a_2}{b_2}\rfloor y_1=0 \\ \therefore x_2=y_1,&y_2=x_1-\lfloor\frac{a_2}{b_2}\rfloor y_1 \end{aligned}
a2x2+b2y2a2x2+b2y2a2x2+b2y2a2x2+b2y2(x2−y1)a2∵a2,b2∴x2−y1=0,∴x2=y1,=a1x1+b1y1=gcd(a,b)=b2x1+(a2modb2)y1=b2x1+(a2−⌊b2a2⌋b2)y1=b2x1+a2y1−⌊b2a2⌋b2y1+(y2−x1+⌊b2a2⌋y1)b2=0=0y2−x1+⌊b2a2⌋y1=0y2=x1−⌊b2a2⌋y1
然后就很显然了,我们在之前求
gcd
\gcd
gcd的代码上简单修改就可以了好像还不少
然后注意我们最后求的是
x
x
x的最小整数解,也就是说
x
x
x不保证是一个正数
要加回来
下面给出
e
x
g
c
d
exgcd
exgcd的核心代码
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return a;
}
int _gcd=exgcd(b,a%b,x,y);
ll z=y;
y=x-a/b*y;
x=z;
return _gcd;
}