一.扩展欧几里得算法是求a*x+b*y=c的通解。
二.若a*x+b*y=c有解,设t=gcd(a,b),则c%t=0。
三.证明: 1.设a*x+b*y=t,当b=0时,t=a(为什么?因为gcd算法,if(b==0) return a;),则有a*x=a,易得x=1.
2.设a*x1+b*y1=gcd(a,b),b*x2+(a%b)*y2=gcd(b,a%b);由于gcd(a,b)=gcd(b,a%b),联立有:a*x1+b*y1=b*x2+(a%b)*y2。
3.a%b=a-floor(a/b)*b;(floor表示向下取整)。
4.将3的结论带入2的等式:a*x1+b*y1=b*x2+[a-floor(a/b)*b]*y2;
5.将a,b示为未知数:整理等式:a*x1+b*y1=a*y2+[x2-y2*floor(a/b)]*b;
6.由5的等式:x1=y2, y1=x2-(a/b)*y2;(计算机整数除法为向下取整);
则得到扩展欧几里得递归做法(实质为层层迭代,当b=0时,x=1,然后往上迭代):
int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=ex_gcd(b,a%b,x,y);//获得x2,y2;
int temp=x;//存储x2
x=y;//x1=y2
y=temp-(a/b)*x;//y1=x2-(a/b)*y2
return ans;
}
前文已经说了,求出来的x,y有 a*x+b*y=gcd(a,b);
易构造:a*(x+n*b)+b*(y+n*a)=gcd(a,b);
则得到 x=x1+n*b y=y1+n*a;
但要注意:x,y并不是其方程所有解。
设 a1=a/gcd(a,b); b1=b/gcd(a,b);
则 a1*x+b1*y=1;
此时x=x+n*b,y=y+n*a为其通解
最小正整数解:
while(x<0)
{
x+=b1;
y+=a1;
}