扩展欧几里得算法-复习
求解二元一次方程
问题
希望求出 \(ax+by=c\) 形式的二元一次不定方程的一组整数解。
思路点拨
首先,这样的方程不一定有正整数解。比如 \(6x+12y=5\) 。
判定
定义:设 \(a,b\) 是不为 \(0\) 的整数,那么一定存在整数 \(x,y\) ,满足 \(ax+by=\gcd(a,b)\) 。
证明:
1.若任何一个等于 \(0\) ,则 \((a,b)=a\) ,这是定理显然成立。
- 若 \(a,b\) 不等于 \(0\) ,设 \(a,b >0 ,b \leqslant a,(a,b)=d\) 。
对于 \(ax+by=d\) ,两端同除以 \(d\) ,可得 \(a_1x+b_1y=d\) 。并且 \((a_1,b_1)=1\) 。我们只考虑对于 \((a,b)=1\) 的二元组 \((a,b)\) ,满足裴蜀定理。
我们考虑辗转相除法(本质上是优化的更相减损术的优化,上已证明),就是 \((a,b)=(b,a \bmod b)\) 一直不断推出来的。我们设余数为 \(r\) ,有
我们算法展开成带余数除法的形式:
我们令辗转相除法运行知道互质的时候推出 \(r_n=1\) ,所以有:
移项,得:
那么我们将 \(r_{n-1}=r_{n-3}-q_{n-1}r_{n-2}\) 带入上式,得:
我们可以不断消除 \(r_{n-2}\) 到 \(r_1\) 。最终得出 \(1=ax+by\) 。得证。
所以 \(ax+by=c\) 需要满足 \(\gcd(a,b)|c\) 。
求解
我们考虑求解 \(ax+by=\gcd(a,b)\) ,最后只需要将 \(x,y\) 同乘上 \(\dfrac{c}{\gcd(a,b)}\) 即可。
对于 \(ax+by=\gcd(a,b)\) ,考虑另一个方程 \(bx_0+(a\bmod b)y_0= \gcd(a,b)\) 。这个方程等价于
在 \(ax+by=\gcd(a,b)\) 中,我们令 \(x=y_0,y=x_0-\lfloor \frac{a}{b}\rfloor y_0\) ,我们就发现这等价于第二个方程。所以如果我们求出 \(bx_0+(a\bmod b)y_0= \gcd(a,b)\), 就可以推出 \(ax+ by=\gcd(a,b)\) 的一组解。
我们考虑在欧几里得算法的过程中,一直如此递归最终可以得出方程 \(ax=a\) ,得到 \(x=1,y=0\) 。一直往上顺推回去,得到原方程的一组解。
int exgcd(int a,int b,int &x,int &y){
if(!b){
x=1,y=0;
return a;
}
int ans=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return ans;
}