理解欧几里德,那么扩展欧几里德就能很容易理解了,对任意a,b(a>b),我们列出这样一个式子: a*x+b*y=gcd(a,b);
不要觉得扩展欧几里德很牛逼,它就是一个算x,y的一个方法,只是在上面gcd中多了处理x,y的步骤
我们这样来想:
已知当前的一个状态:a1 b1 x1 y1, a1*x1+b1*y1=gcd(a1,b1),注意这里的a1,b1是求gcd(a,b)中的一个状态,
假设 (a1,b1)是由(a0,b0)转移过去的
那么: a1=b0 ; b1=a0%b0=a0-k*b0 (k=int(a0/b0)); gcd(a0,b0)=gcd(a1,b1);
代入a1*x1+b1*y1=gcd(a1,b1), 变化成:b0*x1+(a0-k*b0)*y1=gcd(a1,b1)=gcd(a0,b0);
a0*y1+b0*(x1-k*y1)=gcd(a0,b0);
这样可以得到: x0=y1; y0=x1-k*y1;(理解这个过程了么,由当前状态可以算出上一状态的x,y,即当前状态可以由它的下一个状态的x,y得到)。
int exGcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return a;// 此时a是最开始(a,b)的最大公约数,那么 gcd(a,b)*1+ 0*0=gcd(a,b),肯定对的,在这里,我认为,y可以为任何值都对 } int d=exGcd(b,a%b,y,x); y-=a/b*x; return d;//返回最大公约数 }
需要注意一点的就是方程得到的解不止一个是一个通解!
关于求解二元一次不定方程ax+by=c
首先,如果c不是gcd(a,b)的倍数,方程显然无解。
扩展欧几里得求解的是ax+by=gcd(a,b)=1的可行解,但是题目中并没有说c与a,b互质之类的条件,所以需要在开始时两边同时除以gcd(a,b)。
设d=gcd(a,b)
设a'=a/d,b'=b/d,c'=c/d,
则下面需要求解a'x+b'y=c'的整数解,而gcd(a',b')=1,
则我们只需求a'x+b'y=1的可行解
直接使用扩展欧几里得,得到(x',y'),则最终解为x'*c',y'*c'设为(x0,y0)。
现在得到了一组可行解,但是如何得到通解呢?
将(x0,y0)代入ax+by=c,则有
a*(x0)+b*(y0)=c
通过拆添项,可有:
a*(x0+1*b)+b*(y0-1*a)=c
a*(x0+2*b)+b*(y0-2*a)=c
a*(x0+3*b)+b*(y0-3*a)=c
……
a*(x0+k*b)+b*(y0-k*a)=c (k∈Z)
至此,我们得到了通解的方程
x=x0+k*b
y=y0-k*a (k∈Z)
这样,所有满足ax+by=c的可行解都可求出。