1. 程式人生 > >擴展歐幾裏得

擴展歐幾裏得

擴展歐幾裏得 -s 兩個 函數 一個 最小 相減 size lcm

對於方程 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為已經求出的一個解)

擴展歐幾裏得