一.擴展歐幾里得算法是求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;
}