扩展欧几里得算法用于求解形如
$ ax+by=gcd(a,b) $
的方程(其中(a),(b)是常量且(>=0))
首先如果(b=0),则显然有(x=1),(y=0)满足上方程
然后如果(b>0)的话:
首先我们知道$ gcd(a,b) = gcd(b, a mod b ) $(欧几里得算法求两数gcd的原理)
设上面那个方程的通解为 (x_0) , (y_0)
所以就有
$ a×x_0+b×y_0=gcd(a,b) $
那么
$ b×x_0+( a mod b )×y_0=gcd(b, a mod b )=gcd(a,b) $
这里证明个小结论(神仙都是脑补吧……)
(a mod b = a-b×[a/b]),其中[]表示取整
设(a=k×b+m)
(a mod b=m)
([a/b]=k),
那么(a-b×[a/b]=a-k×b=m=a mod b)
然后就有
$ b×x_0+( a mod b )×y_0=b×x_0+(a-b×[a/b])×y_0 $
展开,再整理能得到
(a×y_0+b×(x_0-y_0×[a/b]))
然后上面一长串式子连等下来可以得到
(a×y_0+b×(x_0-y_0×[a/b])=gcd(b, a mod b )=gcd(a,b)=ax+by)(最后=开始的)
观察等式两边得到
(x=y_0),(y=x_0-y_0×[a/b])
然后就可以根据上面过程开始递归了,注意判下边界((b=0))
从lyd书上抄了个代码过来觉得好像理解得更透彻了一点……
所以说学习要勤抄代码(雾
代码我丢一下
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;y=0;return a;
}
int d=exgcd(b,a mod b,x,y);
int z=x;x=y;y=z-y*(a/b);
return d;
}