\(GCD(a,b)=GCD(b,a\%b)\)spa
設\(a=bk+c\),顯然有\(c=a\%b\)。設\(d|a\ \ \ d|b\),則code
\[ c=a-bk \]遞歸
\[ \frac{c}{d}=\frac{a}{d}-\frac{b}{d}k \]element
由右邊的式子可知\(\frac{c}{d}\)爲整數,即\(d|c\)因此對於\(a,b\)的公約數,它也會是\(a\%b\)的公約數。io
反過來也須要證實class
設\(d|b\ \ \ d|(a\%b)\),咱們仍是能夠像以前同樣獲得如下式子擴展
\[ \frac{a\%b}{d}=\frac{a}{d}-\frac{b}{d}k \]gc
\[ \frac{a\%b}{d}+\frac{b}{d}k=\frac{a}{d} \]方法
由於左邊式子顯然爲整數,因此\(\frac{a}{d}\)也爲整數,即\(d|a\),因此\(b,a\%b\)的公約數也是\(a,b\)的公約數。di
既然兩式公約數都是相同的,那麼最大公約數也會相同
因此獲得式子
\[ gcd(a,b)=gcd(b,a\%b) \]
因此咱們能夠寫出一個遞歸式,層層深刻,直到 \(b%(a%b)==0\),即正好爲倍數整除時,遞歸回去就好了
int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); }
最後的返回值天然爲\(a,b\)的最大公因數
目的:求\(ax+by=gcd(a,b)\)的一組可行解
證實
---
設
\[ ax_1+by_1=gcd(a,b) \]
\[ bx_2+(a\,mod\,b)y_2=gcd(b,a\,mod\,b) \]
由歐幾里得定理可知:
\[ gcd(a,b)=gcd(b,a\,mod\,b) \]
因此
\[ ax_1+by_1=bx_2+(a\,mod\,b)y_2 \]
又由於
\[ a\,mod\,b=a-(\lfloor\frac{a}{b}\rfloor*b) \]
因此
\[ ax_1+by_1=bx_2+(a-(\lfloor\frac{a}{b}\rfloor*b))y_2 \]
\[ ax_1+by_1=ay_2+bx_2-\lfloor\frac{a}{b}\rfloor*by_2=ay_2+b(x_2-\lfloor\frac{a}{b}\rfloor y_2) \]
由於\(a=a,b=b\),因此
\[ x_1=y_2 \]
\[ y_1=x_2-\lfloor\frac{a}{b}\rfloor y_2 \]
將\(x_2,y_2\)不斷代入遞歸求解直至\(GCD\)爲0遞歸\(x=1,y=0\)回去求解,就像\(GCD\)同樣的方法
int Exgcd(int a,int b,int &x,int &y) { if (!b) { 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; }
返回的值爲\(GCD\),在這個過程當中計算\(x,y\)便可