扩展欧几里得学习小记

扩展欧几里得是干什么的?给定两个数a,b,设Gcd(a,b)=d(d是a,b的最大公约数),则存在整数x,y,使得x*a+y*b=d。

扩展欧几里得可以求出x,y。怎么求呢?我们知道,Gcd(a,b)=Gcd(b,a%b),而我们也就是运用这个东西来求a和b的最大公约数的。

因此,设bx+(a%b)y=d,即bx+(a-a/b*b)y=d,所以:ay+b*(x-a/b*y)=d。因此我们可用下面的代码解决:

 

int64 exGcd(int64 a,int64 b,int64 &x,int64 &y)
{
    int64 r,t;
    if(b==0)
   {
       x=1;
       y=0;
       return a;
   }
   r=exGcd(b,a%b,x,y);
   t=x;
   x=y;
   y=t-a/b*y;
   return r;

}

这个程序返回值为Gcd(a,b),ax+by=Gcd(a,b),其中x,y分别存在x,y中。

当然,如果给出的是求ax+by=c,这时当且仅当Gcd(a,b)可以整除c时x,y有整数解。这个很好证明,设Gcd(a,b)=d,那么a=d*k1,b=d*k2,所以ax+by=d*(k1*x+k2*y),即ax+by必为d的倍数,所以c必为d的倍数,即d必能整除c。这样的话,先求ax+by=d的一组解x0,y0,设k=c/d,则k*x0,k*y0就是一组解。

 

另外,扩展欧几里得可以求乘法逆元。乘法逆元的意思就是对于a,p,若存在b使得ab%p=1,则称b为a对p的乘法逆元。那么这个b有什么意思呢?对于一个数x,x/a%p=x*b%p(a可以整除x)。这样的话,就可以将除法变为乘法,那么为什么上式成立呢?设x=k*a,则x/a%p=k%p=(k%p)*(ab%p)=(k*a*b)%p=x*b%p。那么怎么求b呢?ab%p=1,我们可得ab=kp+1(k为某个整数),即ab-kp=1,令x=b,y=-k,则我们求出ax+py=1的一组解x,y即可。这个式子有解的充要条件是Gcd(a,p)=1.

证明如下:

(1)若Gcd(a,p)=1,有欧拉定理,设Ψ(x)表示x的欧拉函数(Ψ(x)是一个数,是[1,x-1]中与x互质的数的个数),(a^Ψ(x))%p=1,所以b=a^(Ψ(x)-1)就是一个答案;

(2)若ab%p=1,则ab=kp+1,ab-kp=1,设Gcd(a,p)=d,则d必能整除1,所以d只能是1。

这样的话就能用上面的代码求了。。。

原文地址:https://www.cnblogs.com/jianglangcaijin/p/3446822.html