扩展gcd

来源:互联网 发布:C# js escape 编辑:程序博客网 时间:2024/05/18 20:10

相信大家已经学会如何解二元一次方程组了
对于{a1x+b1y=c1a2x+b2y=c2 在有解的情况下
{x=b2c1b1c2a1b2a2b1y=a1c2a2c1a1b2a2b1{x=|c1 b1c2 b2||a1 b1a2 b2|y=|a1 c1a2 c2||a1 b1a2 b2|

但是对于不定方程ax+by=c(a,b,c为整数)怎么求出其中一组整数解呢?

首先我们记d=gcd(a,b),如果c%d0(“%”表示取模”mod”,下同),那么方程ax+by=c无整数解,(表示不会证,具体参看贝祖定理)

那么根据裴蜀定理(其实是一个东东),可得对于ax+by=c(d|c)都有一组整数解

c=c/d,x=x/c,y=y/c 有方程ax+by=gcd(a,b),最后求出x,y即可。


那么对于方程ax+by=gcd(a,b)如何去解呢?

首先我们知道gcd(a,b)=gcd(b,a%b)

prove:
若a < b ,则a%b=agcd(b,a%b)=gcd(b,a)=gcd(a,b)
若a > b ,则a%b=akb(kN+)
c=gcd(a,b),a=pc,b=qcp,q,a%b=(pkq)c
gcd(q,kq)=q,p,qpkqp(modq)gcd(q,pkq)=1
gcd(b,a%b)=gcd(qc,(pkq)c)=c=gcd(a,b)

有了上面这个定理后,方程可以进行如下变换:
ax+by=gcd(a,b)bx+(a%b)y=gcd(b,a%b)
gcd(a,b)=gcd(b,a%b)ax+by=bx+(a%b)y=bx+(a[ab]b)y
ax+by=ay+b(x[ab]y)
我们设f(a,b)=(x,y) 表示方程ax+by=gcd(a,b)的一组整数解x,y
f(b,a%b)=(x,y)
对于任意a,b要使式子①成立有x=y,y=x[ab]y
b=0x=1,y=0

所以扩展GCD是个以普通GCD为基础的递归。

代码如下:

void exGcd(long long a,long long b,long long &x,long long &y){      if(b==0){x=1,y=0;return;}      exGcd(b,a%b,x,y);      long long t=y;y=x-a/b*y;x=t;  }  
原创粉丝点击