擴展歐幾裏得
對於方程 ax+by=c(x,y為整數),當且僅當 c%gcd(a,b)==0 時,(x,y)有解(見證明3),且有gcd(a,b)組解。
求出方程的一個解x,方程的最小正整數解x0 = (x%(b/gcd(a,b) ) + b/gcd(a,b)) % b/gcd(a,b) (見證明4)
那麽 exgcd(int a,int b,int &x,int &y)為求解該方程的函數,這個函數的返回值為 gcd(x,y),代碼如下
int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x = 1; //解釋見證明1
y = 0; //解釋見證明1
return a;
}
else
{
int r = exgcd(b,a%b,y,x); //解釋見證明2
y -= a/b*x; //解釋見證明2
return r;
}
}
相關證明:
證明1:當b=0時,gcd(a,b)= a,那麽有 ax=a, 得x=1,y=0。
證明2:有裴蜀定理得知:a*x1 + b*y1 = gcd(a,b) 一定成立,
那麽得:b*x2 + (a%b)*y2 = gcd(a,b)
那麽得:b*x2 + (a - a/b*b)*y2 = gcd(a,b)
那麽得:b*x2 + a*y2 - a/b*y2*b = gcd(a,b)
那麽得:a*y2 + b(x2 - a/b*y2) = gcd(a,b)
因為:a*x1 + b*y1 = gcd(a,b)
所以: x1= y2,y1 = (x2 - a/b*y2
證明3: 結論 對於方程 ax+by=c(x,y為整數),當且僅當 c%gcd(a,b)==0 時有解
設 f = c mod (gcd(a,b)),那麽f的取值範圍應為 : 0 <= f < gcd(a,b)
有裴蜀定理知道:ax + by = gcd(a,b)
可設:k*gcd(a,b) + f = c
那麽:k*a*x + k*b*y + f = c
若 f != 0,因為0 <= f < gcd(a,b),所以 f = m*a(m為整數)不成立,所以 k*a*x + k*b*y + ma = c 不成立
所以 f應為0,那麽 c mod (gcd(a,b)) 應為 0。
證明4:設c = gcd(a,b),相鄰的兩組解之間的間隔為dx
得:a*x = d(mod b),
a*(x+dx) = d(mod b)
兩個式子相減得 : a*dx % b = 0
a*dx 是b的整數倍,也是a的整數倍,所以lcm(a,b)所對應的dx值最小
lcm(a,b) = a*b/c
所以 a*dx = a*b/c,所以 dx = b/c
所以最小解x0為:(x%dx + dx)%dx,(x為已經求出的一個解)
擴展歐幾裏得