扩展欧几里得(学习笔记)

贝祖定理:对于任意整数a,b,存在一对整数x,y,满足\(ax+by=gcd(a,b)\).

以下证明中的[ ]是向下取整的意思(主要是我不会打向下取整的符号)

证明:数学归纳法.在欧几里得算法最后一步中,即b=0时,显然有一对整数x=1,y=0,使得\(a*1+0*0=gcd(a,0)\);若b>0,则\(gcd(a,b)=gcd(b,a\mod b)\).假设存在一对整数x,y,满足\(b*x+(a \mod b)*y=gcd(b,a \mod b)\),因为\(bx+(a \mod b)y=bx+(a-b[a/b])y\),继续整理式子得\(ay+b(x-[a/b]y)\),所以令\(x'=y\)\(y'=x-[a/b]y\),就得到了\(ax'+by'=gcd(a,b)\).因为x'和y'一定都是整数,所以定理是成立的.

根据上述定理和证明,有扩展欧几里得算法:

int exgcd(int a,int b,int &x,int &y){
     if(b==0){x=1;y=0;return a;}
     int d=exgcd(b,a%b,x,y);
     int z=x;x=y;y=z-y*(a/b);
     return d;
}

还有一种写得更多的写法,个人认为更好理解:

int exgcd(int a,int b,int &x,int &y){
     if(b==0){x=1;y=0;return a;}
     int d=exgcd(b,a%b,y,x);
     y-=(a/b)*x;
     return d;
}

拓展:

对于更一般的方程\(ax+by=c\),它有解当且仅当\(gcd(a,b)|c\).

\(d=gcd(a,b)\),我们可以先用扩展欧几里得求出\(ax+by=d\)的一组特解\(x_0\)\(y_0\),然后令\(x_0\),\(y_0\)同时乘上\(c/d\),就得到方程\(ax+by=c\)的一组特解\((c/d)*x_0\),\((c/d)*y_0\),所以通解就是\((c/d)*x_0+k*(b/d)\),\((c/d)*y_0+k*(a/d)\),其中k是整数.

扩展欧几里得算法有一个常见的应用:求解线性同余方程.

给定整数a,b,m,求一个整数x满足\(a*x ≡ b(\mod m)\),或者给出无解.因为未知数的指数为1,所以称为一次同余方程,也称线性同余方程.

\(a*x ≡ b(\mod m)\) 方程可以改写为\(a*x+m*y=b\).这就回到了上面的拓展内容.

推荐两道模板题练练手,同余方程青蛙的约会

posted on 2019-03-09 14:34  PPXppx  阅读(157)  评论(0编辑  收藏  举报