前言
本文讨论如何求下面方程的解(a,b已知):
a
x
+
b
y
=
1
(
x
,
y
∈
Z
)
ax+by=1(x,y \in Z)
ax+by=1(x,y∈Z)
首先,方程有没有可能无解?
例如当
a
=
2
,
b
=
4
a=2,b=4
a=2,b=4 时,显然方程是无解的。
方程何时有解?
方程有解的充分必要条件是 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,即 a , b a,b a,b 互质。
简单证明如下:
我们不妨考虑
a
,
b
a,b
a,b 为正整数的情况,令
g
c
d
(
a
,
b
)
=
g
gcd(a,b)=g
gcd(a,b)=g,则
a
=
k
1
g
,
b
=
k
2
g
(
k
1
,
k
2
∈
N
)
a=k_1g,b=k_2g(k1,k2 \in N)
a=k1g,b=k2g(k1,k2∈N),则
a
x
+
b
y
=
k
1
g
∗
x
+
k
2
g
∗
y
ax+by=k_1g*x+k_2g*y
ax+by=k1g∗x+k2g∗y。显然结果必是 g 的倍数,那么,当且仅当 g 为 1 时,原方程可能有解。
下面证明
g
c
d
(
a
,
b
)
=
1
gcd(a,b)=1
gcd(a,b)=1 时,方程必有解。
因
g
c
d
(
a
,
b
)
=
1
gcd(a,b)=1
gcd(a,b)=1,则说明
a
,
b
a,b
a,b 不断辗转相减一定会等于 1。而两数辗转相减的结果是可以表达成
a
∗
t
1
+
b
∗
t
2
a*t_1+b*t_2
a∗t1+b∗t2 的,所以
(
t
1
,
t
2
)
(t_1,t_2)
(t1,t2) 即是原方程的解。
结论
- 当 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1 时,方程 a x + b y = 1 ax+by=1 ax+by=1,一定存在整数解 ( x , y ) (x,y) (x,y)。
- 扩展的可知, a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b) 也一定存在整数解 ( x , y ) (x,y) (x,y)
由此我们引出扩展欧几里得算法
扩展欧几里得算法
接下来,我们看一下如何求下面方程的整数解 (x,y) 之一.
a x + b y = g c d ( a , b ) (1) ax+by=gcd(a,b) \tag{1} ax+by=gcd(a,b)(1)
对于 ( 1 ) (1) (1) 式,当 b = 0 b=0 b=0 时, a x + b y = g c d ( a , b ) = a ax+by=gcd(a,b)=a ax+by=gcd(a,b)=a,显然 ( x = 1 , y = 0 ) (x=1,y=0) (x=1,y=0) 是方程的一个解.
当
b
b
b 不为
0
0
0 时,根据欧几里得定理
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
gcd(a,b)=gcd(b,a \bmod b)
gcd(a,b)=gcd(b,amodb) 可得
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
⇒
a
x
+
b
y
=
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
=
b
x
′
+
(
a
m
o
d
b
)
y
′
⇒
a
x
+
b
y
=
b
x
′
+
(
a
m
o
d
b
)
y
′
=
b
x
′
+
(
a
−
b
∗
⌊
a
/
b
⌋
)
y
′
移项得
a
x
+
b
y
=
a
y
′
+
b
(
x
′
−
⌊
a
/
b
⌋
y
′
)
\begin{aligned} gcd(a,b) & =gcd(b,a \bmod b)\\ \Rightarrow \qquad ax+by=gcd(a,b) & =gcd(b,a \bmod b)=bx^{\prime}+(a \bmod b)y^{\prime}\\ \Rightarrow \qquad \qquad\qquad\quad ax+by &=bx^{\prime}+(a \bmod b)y^{\prime}=bx^{\prime}+(a−b∗⌊a/b⌋)y^{\prime}\\ \text{移项得}\qquad \qquad ax+by &=ay^{\prime}+b(x^{\prime}−⌊a/b⌋y^{\prime}) \end{aligned}
gcd(a,b)⇒ax+by=gcd(a,b)⇒ax+by移项得ax+by=gcd(b,amodb)=gcd(b,amodb)=bx′+(amodb)y′=bx′+(amodb)y′=bx′+(a−b∗⌊a/b⌋)y′=ay′+b(x′−⌊a/b⌋y′)
根据恒等定理,有 { x = y ′ y = x ′ − ⌊ a / b ⌋ y ′ \text{根据恒等定理,有}\qquad \begin{cases} x=y^{\prime}\\ y=x^{\prime}−⌊a/b⌋y^{\prime} \end{cases}\qquad\qquad\qquad\qquad\qquad\quad 根据恒等定理,有{x=y′y=x′−⌊a/b⌋y′
这有什么用呢? x′ 和 y′ 还是不知道呀.
重新来看看我们得到的两个等式。x 和 y 是
g
c
d
(
a
,
b
)
=
a
x
+
b
y
gcd(a,b)=ax+by
gcd(a,b)=ax+by 的解,而
x
′
x'
x′ 和
y
′
y'
y′ 是在对 gcd(a,b) 按欧几里德算法进行一步后的结果对应的贝祖等式
g
c
d
(
b
,
a
m
o
d
b
)
=
b
x
′
+
(
a
m
o
d
b
)
y
′
gcd(b,a\ mod\ b)=bx′+(a\ mod\ b)y′
gcd(b,a mod b)=bx′+(a mod b)y′ 的解.也就是说,gcd(a,b)对应的贝祖等式的解 x,y 可以由gcd(b,a mod b) 对应等式的解
x
′
,
y
′
x',y'
x′,y′ 计算得出.
说的通俗点,由于欧几里德算法最后一步为 g c d ( a , 0 ) = a gcd(a,0)=a gcd(a,0)=a
此时对应的等式的解为 x = 1 , y = 0 x=1,y=0 x=1,y=0,因此只需从最后一层 1 a + 0 b = g c d ( a , 0 ) = a 1a+0b=gcd(a,0)=a 1a+0b=gcd(a,0)=a 向上一层递推求解.
即在进行欧几里德算法的递归的时候根据相邻两次调用间 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; //边界解,1a+0b=gcd(a,0)=a
return a;
}
int r=exGcd(b,a%b,x,y); //求下一层的解(x',y')
int t=x;x=y;y=t-a/b*y; //根据下一层的解(x',y'),求出本层的解(x,y)
return r;
}
解的范围
递归算到最后 y 其实可以取任意整数。但是取的太大容易导致使得最后算出来的解爆 int 之类的事情
下面我们来看一下最终算出来的解 x,y 的绝对值大小情况
由 x y 的计算方法 x -= (a / b) * y
可以知道,x y 始终是在
max
(
∣
a
∣
,
∣
b
∣
)
\max(|a|, |b|)
max(∣a∣,∣b∣) 的绝对值范围内的,因此
a
∗
x
+
b
∗
y
=
g
c
d
(
a
,
b
)
a*x + b*y = gcd(a, b)
a∗x+b∗y=gcd(a,b) 最后算出的 x y 的绝对值大小跟 a b 是同一个级别的,不用担心爆。
如何得到所有解?
实际上,在之前的计算中,我们得到的只是不定方程的一组解,方程难道只有一组解吗?
显然,若
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b),则
a
(
x
+
b
)
+
b
(
y
−
a
)
=
g
c
d
(
a
,
b
)
a(x+b)+b(y-a)=gcd(a,b)
a(x+b)+b(y−a)=gcd(a,b) 也成立,所以解有无数个。
那么怎样得到所有解呢?
对于一般形式
a
x
+
b
y
=
g
ax+by=g
ax+by=g 有通解
(
x
,
y
)
(x,y)
(x,y) ,则
x
′
=
x
+
b
/
g
,
y
′
=
y
−
a
/
g
x'=x+b/g,y'=y−a/g
x′=x+b/g,y′=y−a/g .(证明略,只要代入一下就知道为什么通解是这个了)
更进一步,对于任意不定式 ax′+by′=c,只需要在等式 ax+by=gcd(a,b)=d 两边乘上c/d即可得到解为x′=x∗c/d,y′=y∗c/d