歐幾里得算法


歐幾里得算法:

輾轉相除計算兩個數的最大公約數。求gcd(a,b)。

代碼:

int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}

 

擴展歐幾里得算法:

存在整數對(x,y)使得ax + by = gcd(a,b)

證明:

設a > b

當b = 0時,a * 1 + b * 0 = a = gcd(a,b), 此時x = 1,y = 0;

當b!= 0 時,設

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

a * x1 + b * y1 == b* x2 +(a-(a/b)*b)*y2

則 x1 = y2,y1 = x2 - (a/b) * y2;

代碼:

int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x
= 1;
y
= 0;
return a;
}
int d = exgcd(b,a%b,x,y);
int t = x;
x
= y;
y
= t - a/b * y;
return d;
}

應用:

1.求解不定方程:

c%gcd(a,b)=0,則存在整數對(x,y)使得ax+by=c

 

通過上面的方法可得到一組特解x0y0使得ax+by=gcd(a,b),那么如何在無窮多個解中求出xy最小正整數解。

證明:

首先 ax0+akb/gcd(a,b)+by0akb/gcd(a,b)=gcd(a,b) 
即 a(x0+kb/gcd(a,b))+b(y0ka/gcd(a,b))=gcd(a,b) 
通解為x=x0+kb/gcd(a,b)y=y0ka/gcd(a,b),其中k=...2,1,0,1,2... 
在所有解中最小的正整數為(x0+b/gcd(a,b))%(b/gcd(a,b)), 
所以對於方程ax+by=c,最小正整數解(以x為例)為(x0c/gcd(a,b)+b/gcd(a,b))%(b/gcd(a,b)) 
注意:若b為負數,需將b轉換為正數。

代碼:

int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x
= 1;
y
= 0;
return a;
}
int d = exgcd(b,a%b,x,y);
int t = x;
x
= y;
y
= t - a/b * y;
return d;
}
int cal(int a,int b,int c)
{
int x,y;
int g = ex_gcd(a,b,x,y);
if(c%g!=0)
return -1;
x
*= c/g; ///x0 * c/gcd(a,b);

b
/= g;///b/gcd(a,b);
if(b<0)
b
= -b;
int ans = x%b;
if(ans<=0) ans +=b;
return ans;
}

 

2.同余定理:

根據上面的內容,我們可以得到:

  • axb(modn),轉化為ax+ny=b,當 b%gcd(a,n)=0時,方程有 gcd(a,n) 個解。
  • ax1(modn),如果gcd(a,n)=1,則方程有唯一解。

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com