一、内容
∀
a
,
b
∈
Z
\forall a,b\in Z
∀a,b∈Z, 则
∃
x
,
y
∈
Z
\exists x,y \in Z
∃x,y∈Z, 满足方程
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b)
ps : 该方程有多组解x,y。
二、通解推导
对于方程
a
x
1
+
b
y
1
=
g
c
d
(
a
,
b
)
,
a
x
2
+
b
y
2
=
g
c
d
(
a
,
b
)
ax_1+by_1=gcd(a,b), ax_2+by_2=gcd(a,b)
ax1+by1=gcd(a,b),ax2+by2=gcd(a,b)
将两式相减:
a
(
x
1
−
x
2
)
=
b
(
y
2
−
y
1
)
a(x_1-x_2)=b(y_2-y_1)
a(x1−x2)=b(y2−y1)
等式两边同时除以
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b):
a
′
(
x
1
−
x
2
)
=
b
′
(
y
2
−
y
1
)
a'(x_1-x_2)=b'(y_2-y_1)
a′(x1−x2)=b′(y2−y1)
从而
b
′
∣
a
′
(
x
1
−
x
2
)
b'|a'(x_1-x_2)
b′∣a′(x1−x2)。又因为
a
′
,
b
′
a',b'
a′,b′互质,所以
b
′
∣
(
x
1
−
x
2
)
b'|(x_1-x_2)
b′∣(x1−x2)。令
(
x
1
−
x
2
)
/
b
′
=
k
(x_1-x_2)/b'=k
(x1−x2)/b′=k,则
x
1
=
x
2
+
k
∗
b
′
=
x
2
+
k
∗
b
g
c
d
(
a
,
b
)
x_1=x_2+k*b'=x_2+k*\frac b {gcd(a,b)}
x1=x2+k∗b′=x2+k∗gcd(a,b)b
同理可以得到:
y
1
=
y
2
−
k
∗
a
g
c
d
(
a
,
b
)
y_1=y_2-k*\frac a {gcd(a,b)}
y1=y2−k∗gcd(a,b)a
所以最后得到通解为:
{
X
=
x
+
k
1
∗
b
g
c
d
(
a
,
b
)
Y
=
y
−
k
2
∗
a
g
c
d
(
a
,
b
)
\begin{cases} X=x+k_1*\frac b {gcd(a,b)}\\ Y=y-k_2*\frac a {gcd(a,b)} \end{cases}
{X=x+k1∗gcd(a,b)bY=y−k2∗gcd(a,b)a
其中x, y为扩展欧几里得算法求出来的一组解。
三、算法推导
若
a
x
1
+
b
y
1
=
g
c
d
(
a
,
b
)
(1)
ax_1+by_1=gcd(a,b) \tag1
ax1+by1=gcd(a,b)(1)
则用
b
b
b替换
a
a
a,
a
%
b
a \% b
a%b替换
b
b
b, 得到
b
x
2
+
(
a
%
b
)
y
2
=
g
c
d
(
b
,
a
%
b
)
(2)
bx_2+(a\%b)y_2=gcd(b,a\%b) \tag2
bx2+(a%b)y2=gcd(b,a%b)(2)
如果找到了
x
1
,
x
2
x_1,x_2
x1,x2的关系以及
y
1
,
y
2
y_1,y_2
y1,y2的关系, 就可以利用递归来计算出原方程中的解, 即
x
1
,
y
1
.
x_1,y_1.
x1,y1.
我们将
(
2
)
(2)
(2)进行变形:
b
x
2
+
(
a
−
⌊
a
b
⌋
b
)
y
2
=
g
c
d
(
b
,
a
%
b
)
bx_2+(a - \lfloor{\frac ab}\rfloor b)y_2=gcd(b,a\%b)
bx2+(a−⌊ba⌋b)y2=gcd(b,a%b)
合并同类项得到:
a
y
2
+
b
(
x
2
−
⌊
a
b
⌋
y
2
)
=
g
c
d
(
b
,
a
%
b
)
(3)
ay_2+b(x_2-\lfloor{\frac ab}\rfloor y_2)=gcd(b,a\%b) \tag3
ay2+b(x2−⌊ba⌋y2)=gcd(b,a%b)(3)
由于
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
%
b
)
gcd(a,b)=gcd(b,a\%b)
gcd(a,b)=gcd(b,a%b), 所以由
(
2
)
,
(
3
)
(2),(3)
(2),(3)得:
a
x
1
+
b
y
1
=
a
y
2
+
b
(
x
2
−
⌊
a
b
⌋
y
2
)
(4)
ax_1+by_1=ay_2+b(x_2-\lfloor{\frac ab}\rfloor y_2) \tag4
ax1+by1=ay2+b(x2−⌊ba⌋y2)(4)
对比系数可以得到:
{ x 1 = y 2 y 1 = x 2 − ⌊ a b ⌋ y 2 (5) \begin{cases} x_1=y_2\\ y_1=x_2-\lfloor \frac ab \rfloor y_2 \end{cases} \tag5 {x1=y2y1=x2−⌊ba⌋y2(5)
因此,我们可以先计算出 x 2 , y 2 x_2,y_2 x2,y2, 然后推出原方程的解 x 1 , y 1 x_1,y_1 x1,y1。显然,这是一个递归的过程。
如果我们用
a
%
b
a\%b
a%b替换a,
b
b
b替换
b
b
b, 则
(
2
)
(2)
(2)变成了
b
y
2
+
(
a
%
b
)
x
2
=
g
c
d
(
a
%
b
,
b
)
(6)
by_2+(a\%b)x_2=gcd(a\%b, b) \tag6
by2+(a%b)x2=gcd(a%b,b)(6)
则最后的推导结果为:
{
x
1
=
x
2
y
1
=
y
2
−
⌊
a
b
⌋
x
2
(7)
\begin{cases} x_1=x_2\\ y_1=y_2-\lfloor \frac ab \rfloor x_2 \end{cases} \tag7
{x1=x2y1=y2−⌊ba⌋x2(7)
四、代码部分
/* 采用第二种推导结果 */
int exgcd(int a, int b, int &x, int &y) { // 返回两个值x y,因此传引用
/* 由辗转相除法可知:递归到最后一定是 ax + 0y = gcd(a, 0) = a
所以递归结束的条件为 b == 0,而此时x = 1,y = 0 */
if(b == 0) {
x = 1;
y = 0;
return a;
}
int d = exgcd(b, a % b, y, x); // 参数对应方程 : by + (a % b)x = gcd(b, a%b)
y -= a / b * x;
return d;
}
五、拓展
判断下列不定方程解的情况
a
x
+
b
y
=
c
(8)
ax+by=c \tag8
ax+by=c(8)
先说结论:若
g
c
d
(
a
,
b
)
∣
c
gcd(a,b)|c
gcd(a,b)∣c,则方程一定有解;否则一定无解
1. c % g c d ( a , b ) ! = 0 c \% gcd(a, b) != 0 c%gcd(a,b)!=0
由于等式左边
g
c
d
(
a
,
b
)
∣
a
,
g
c
d
(
a
,
b
)
∣
b
gcd(a,b)|a, gcd(a,b)|b
gcd(a,b)∣a,gcd(a,b)∣b
所以方程一定无解
2. c % g c d ( a , b ) = = 0 c \% gcd(a, b) == 0 c%gcd(a,b)==0
将方程 ( 1 ) (1) (1)两边同时乘上 c g c d ( a , b ) \frac c {gcd(a,b)} gcd(a,b)c,即可得到方程 ( 8 ) (8) (8)的解。所以此时方程一定有解。