前言
本文讨论如何求下面方程的解(a,b已知):
ax+by=1(x,y∈Z)ax+by=1(x,y \in Z)ax+by=1(x,y∈Z)
首先,方程有没有可能无解?
例如当 a=2,b=4a=2,b=4a=2,b=4 时,显然方程是无解的。
方程何时有解?
方程有解的充分必要条件是 gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1,即 a,ba,ba,b 互质。
简单证明如下:
我们不妨考虑 a,ba,ba,b 为正整数的情况,令 gcd(a,b)=ggcd(a,b)=ggcd(a,b)=g,则 a=k1g,b=k2g(k1,k2∈N)a=k_1g,b=k_2g(k1,k2 \in N)a=k1g,b=k2g(k1,k2∈N),则 ax+by=k1g∗x+k2g∗yax+by=k_1g*x+k_2g*yax+by=k1g∗x+k2g∗y。显然结果必是 g 的倍数,那么,当且仅当 g 为 1 时,原方程可能有解。
下面证明 gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1 时,方程必有解。
因 gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1,则说明 a,ba,ba,b 不断辗转相减一定会等于 1。而两数辗转相减的结果是可以表达成 a∗t1+b∗t2a*t_1+b*t_2a∗t1+b∗t2 的,所以 (t1,t2)(t_1,t_2)(t1,t2) 即是原方程的解。
结论
- 当 gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1 时,方程 ax+by=1ax+by=1ax+by=1,一定存在整数解 (x,y)(x,y)(x,y)。
- 扩展的可知,ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b) 也一定存在整数解 (x,y)(x,y)(x,y)
由此我们引出扩展欧几里得算法
扩展欧几里得算法
接下来,我们看一下如何求下面方程的整数解 (x,y) 之一.
ax+by=gcd(a,b)(1)ax+by=gcd(a,b) \tag{1}ax+by=gcd(a,b)(1)
对于 (1)(1)(1) 式,当 b=0b=0b=0 时, ax+by=gcd(a,b)=aax+by=gcd(a,b)=aax+by=gcd(a,b)=a,显然 (x=1,y=0)(x=1,y=0)(x=1,y=0) 是方程的一个解.
当 bbb 不为 000 时,根据欧几里得定理 gcd(a,b)=gcd(b,a mod b)gcd(a,b)=gcd(b,a \bmod b)gcd(a,b)=gcd(b,amodb) 可得
gcd(a,b)=gcd(b,a mod b)⇒ax+by=gcd(a,b)=gcd(b,a mod b)=bx′+(a mod b)y′⇒ax+by=bx′+(a mod b)y′=bx′+(a−b∗⌊a/b⌋)y′移项得ax+by=ay′+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 是 gcd(a,b)=ax+bygcd(a,b)=ax+bygcd(a,b)=ax+by 的解,而 x′x'x′ 和 y′y'y′ 是在对 gcd(a,b) 按欧几里德算法进行一步后的结果对应的贝祖等式 gcd(b,a mod b)=bx′+(a mod 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′ 计算得出.
说的通俗点,由于欧几里德算法最后一步为 gcd(a,0)=agcd(a,0)=agcd(a,0)=a
此时对应的等式的解为 x=1,y=0x=1,y=0x=1,y=0,因此只需从最后一层 1a+0b=gcd(a,0)=a1a+0b=gcd(a,0)=a1a+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=gcd(a,b)a*x + b*y = gcd(a, b)a∗x+b∗y=gcd(a,b) 最后算出的 x y 的绝对值大小跟 a b 是同一个级别的,不用担心爆。
如何得到所有解?
实际上,在之前的计算中,我们得到的只是不定方程的一组解,方程难道只有一组解吗?
显然,若 ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b),则 a(x+b)+b(y−a)=gcd(a,b)a(x+b)+b(y-a)=gcd(a,b)a(x+b)+b(y−a)=gcd(a,b) 也成立,所以解有无数个。
那么怎样得到所有解呢?
对于一般形式 ax+by=gax+by=gax+by=g 有通解 (x,y)(x,y)(x,y) ,则 x′=x+b/g,y′=y−a/gx'=x+b/g,y'=y−a/gx′=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