歐幾里德算法
歐幾里德算法又稱輾轉(zhuǎn)相除法,用于計算兩個整數(shù)a,b的最大公約數(shù)。
基本算法:設(shè)a=qb+r,其中a,b,q,r都是整數(shù),則gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)。
證明:
a可以表示成a = kb + r,則r = a mod b
假設(shè)d是a,b的一個公約數(shù),則有
d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公約數(shù)
假設(shè)d 是(b,a mod b)的公約數(shù),則
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公約數(shù)
因此(a,b)和(b,a mod b)的公約數(shù)是一樣的,其最大公約數(shù)也必然相等,得證
int gcd(int a,int b)
{
if(b==0)
return a;
return
gcd(b,a%b);
}
擴(kuò)展歐幾里德算法
基本算法:對于不完全為 0 的非負(fù)整數(shù) a,b,gcd(a,b)表示 a,b 的最大公約數(shù),必然存在整數(shù)對 x,y ,使得 gcd(a,b)=ax+by。
證明:設(shè) a>b。
1,顯然當(dāng) b=0,gcd(a,b)=a。此時 x=1,y=0;
2,ab!=0 時
設(shè) ax1+by1=gcd(a,b);
bx2+(a mod b)y2=gcd(b,a mod b);
根據(jù)樸素的歐幾里德原理有 gcd(a,b)=gcd(b,a mod b);
則:ax1+by1=bx2+(a mod b)y2;
即:ax1+by1=bx2+(a-(a/b)b)y2=ay2+bx2-(a/b)by2;
根據(jù)恒等定理得:x1=y2; y1=x2-(a/b)*y2;
這樣我們就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以遞歸定義的,因為 gcd 不斷的遞歸求解一定會有個時候 b=0,所以遞歸可以結(jié)束。
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return r;
}