欧几里得扩展算法
欧几里得扩展算法
首先证明欧几里德算法(即最大公约数算法)
设有a,b两个数;
a=k*b+r,r=a%b;
假设d是a,b的一个公约数,a%d=0,b%d=0;r=a-k*b,因此r%d=0;
即所有a,b的公约数都是b,a%b的公约数,那么gcd(a,b)=gcd(b,a%b);
所以当a%b=0时,即a和b的最大公约数就是他们本身;
算法代码
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
gcd(a,b)=gcd(b,r0)=gcd(r0,r1)=...=gcd(rn-1,rn)=gcd(rn-1,0)=rn-1.
接下来讲解欧几里得扩展算法(即求n*a+m*b=gcd(a,b)中的n,m)
首先m*a+n*b=gcd(a,b);
当a=k*b+r;r=0时,m=0,n=1;
当r!=0时,有上述可知m*(k*b+r)+n*b=gcd(a,b)=gcd(b,r);
假设m1*b+n1*r=gcd(b,r);
b=k1*r+r1;当r1=0时,则m1,n1已知;
代入上式 得
m1*b+n1*r=m*(k*b+r)+n*b;
m1*b+n1*r=(m*k+n)*b+m*r;
得 m=n1,n=m1-m*k=m1-n1*a/b;
由于代码中用了引用所以是y-=x*(a/b),仔细理解一下;
void gcd(int a,int b,int& x,int& y)
{
if(!b) x=1,y=0;
else gcd(b,a%b,y,x),y-=x*(a/b);
}
最后总结:
关于欧几里得算法用于求解整数问题和最大公约数(白书179);
虽然可以求出一组解但是本质上是有许多解的,比如已知(x,y),所有解为(x+k*b/gcd(a,b),y-k*a/gcd(a,b));