GCD

GCD-歐幾里得定理(展轉相除)

Elements

\(GCD(a,b)=GCD(b,a\%b)\)spa

Confirmation

\(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) \]

Code

因此咱們能夠寫出一個遞歸式,層層深刻,直到 \(b%(a%b)==0\),即正好爲倍數整除時,遞歸回去就好了

int gcd(int a,int b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}

最後的返回值天然爲\(a,b\)的最大公因數

EXGCD-擴展歐幾里得定理

目的:求\(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\)便可

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息