最大公約數詳解


最大公約數詳解

一般的,設 \(a_1,a_2,...a_n\) ,是 \(n\) 個非零整數,如果存在一個非零整數 \(d\), 使得 \(d\mid a_1,d\mid a_2,...d\mid a_n\) ,那么稱 \(d\) 是這 \(n\) 個數的公約數。顯然可能存在多個公約數,將這些公約數中最大的一個記為 \(\gcd(a_1,a_2,...a_n)\) ,即最大公約數。

特別的,當 \(\gcd(x,y)=1\) 的時候,二者顯然互質。

輾轉相除法

輾轉相除法是用來求最大公約數的,也被稱作歐幾里得算法。

代碼只有一行:

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

小常數版:

int gcd(int a,int b){
    if(a<b)return gcd(b,a);
    while(b){
        int t=a-a/b*b;
        a=b;b=t;
    }
    return a;
}

以下為證明部分(給出了多種證明,可以當跳過)

首先,最大公約數有以下三大性質(以下默認 \(x>y>0\)

  • 公約數都是最大公約數的約數
  • \(\gcd(x,y)=\gcd(x,y-x)\)
  • \(\gcd(x,y)=gcd(y,x \bmod y )\)

其中,第三條可以看作是對第二條的延伸

公約數都是最大公約數的約數

\(x=k_1*d,y=k_2*d\)

\(d\)\(x,y\) 任意一個約數,不保證 \(\gcd(k_1,k_2)=1\quad(d\ne\gcd(x,y))\)

\(k_1=s_1*\gcd(k_1,k_2),k_2=s_2*\gcd(k_1,k_2)\)

其中, \(\gcd(s_1,s_2)\) 顯然為 \(1\),若不為 \(1\),即 \(s_1,s_2\) 仍有公因子,與 \(\gcd\) 定義相違背

\(k_1,k_2\) 帶入 \(x,y\) ,得 \(x=s_1*\gcd(k_1,k_2)*d,y=s_2*\gcd(k_1,k_2)*d\)

因為 \(\gcd(s_1,s_2)=1\) ,所以 \(gcd(x,y)=\gcd(k_1,k_2)*d\)

所以 \(d\mid\gcd(x,y)\)

\(\gcd(x,y)=\gcd(x,y-x)\)

分類討論:

  1. \(z\mid x,z\mid y\)\(z\mid(y-x)\)
  2. \(z \nmid x\) ,則 \(z\) 不是 \(x\)\(y-x\) 的公因子
  3. \(z\mid x,z\nmid y\),則 \(z\) 不是 \(x\)\(y-x\) 的公因子

\(\gcd(x,y)=gcd(y,x \bmod y)\)

證明一

\(\gcd(x,y)=\gcd(x,y-x)=\gcd(x,y-2x)=...=\gcd(x,y\bmod x)\)

證明二

\[\gcd(x,y)=gcd(y,x \bmod y)\Leftrightarrow{\gcd(x,y)\mid \gcd(y,x\bmod y)\\\gcd(y,x\bmod y)\mid\gcd(x,y)} \]

\(x=yq+r,(0\leq r<y)\)

\(r=x\bmod y\)

\(x=k_1*\gcd(x,y),y=k_2*\gcd(x,y)\)

那么 \(r=x-yq=k_1*\gcd(x,y)-k_2*\gcd(x,y)*q=\gcd(x,y)*(k_1-k_2q)\)

所以 \(\gcd(x,y)\mid\gcd(y,x\bmod y)\)

因為 \(x=yq+x\bmod y\)

所以 \(\gcd(y,x\bmod y)\mid\gcd(x,y)\)

證明三

其實和證明二差不多。

\(x\) 可以表示成 \(x = qy + r (0\leq r<y)\),則 \(r = x \bmod y\)

假設 \(d\)\(x,y\) 的一個公約數,即 \(d\mid x,d\mid y\)

\(r = x - qy\),兩邊同時除以 \(d\)\(\frac rd=\frac xd-\frac{qy}d=m\)

由等式右邊可知 \(m\in \Z\) ,因此 \(d|r\)\(d\) 也是 \(y,x \bmod y\) 的公約數

假設 \(d\)\(y,x \bmod y\) 的公約數, 則 \(d\mid y,d\mid (x-qy),q\) 是一個整數, 進而 \(d\mid x\).

因此 \(d\) 也是 \(x,y\) 的公約數.

所以\(x,y\) 和 $y,x \bmod y $ 的公約數集合是一樣的,其最大公約數也必然相等。

裴蜀定理

也叫貝祖定理。

對任何整數 \(a、b\) 和它們的最大公約數 \(d\),關於未知數 \(x\)\(y\) 的線性不定方程(稱為裴蜀等式):若 \(a,b\) 是整數,且\(\gcd(a,b)=d\),那么對於任意的整數 \(x,y,ax+by\) 都一定是 \(d\) 的倍數,特別地,一定存在整數 \(x,y\),使\(ax+by=d\) 成立。 ——百度百科

證明一

裴蜀定理也就是:

\[\left\{\begin{aligned}\forall x,y\to\gcd(a,b)\mid ax+by \\ax+by=\gcd(a,b)有整數解\end{aligned}\right. \]

其中 \(a,b,x,y\in \Z\)

第一個是顯然的,來看看第二個。

這里還有一個引理

\(ax+by\) 的最小正整數取值為 \(\gcd(a,b)\)

顯然,如果這個引理成立,上面那個也成立:

\(t=\gcd(a,b)\)\(t\mid a,t\mid b,t\mid ax+by\)

\(s\)\(ax+by\) 的最小正整數值,有 \(s\)\(a,b\) 的線性組合,

設 $ r=a\bmod s,p=\lfloor\dfrac{a}{s}\rfloor$

\(\therefore r=a-ps=a-p(ax+by)=a(1-px)-pby\)

顯然\(r\)也是\(a,b\)的線性組合

\(\because s\) 最小 \(\quad\therefore r=0\) (注意到前面 \(r=a\%s\)

\(\therefore s|a,s|b,\)那么 \(s\)\(a,b\) 的公因數 \(\rightarrow t \ge s\)

\(\because t|ax+by\quad\therefore t|s\)

\(\therefore t \le s\)

\(\because t \ge s,t \le s\)

\(\therefore t=s\)

證明二

反證法:https://blog.csdn.net/lleozhang/article/details/82935400

但這個證明有一個前提是擴展歐幾里得。

推廣

方程 \(ax+by+cz+...+nm=f(a,b,c,...n,f\in\Z)\) 有整數解的充要條件是 \(\gcd(a,b,c...n)\mid f\)

應用

  1. \(\text{Luogu} 4549\) 【模板】裴蜀定理 https://www.luogu.com.cn/problem/P4549

注意題目中絕對值。

  1. 在模意義下的乘法逆元

即對於給定的 a,b,找到方程\(aa^{-1}\equiv 1(\bmod b)\) 的一個整數解 \(a^{-1}\)

根據同余的定義,有 \(b\mid(aa^{-1}-1)\),也就是存在整數 \(k\) 使得 \(bk=aa^{-1}-1\)。移一下項,就得到了 \(aa^{-1}-bk=1\)

這個形式恰好符合裴蜀定理 \(ax+by=1\) 的形式,於是我們可以通過擴展歐幾里得計算出 \(a^{-1}\)

最小公倍數

插播一下最小公倍數(就是不講擴展歐幾里得)

一般的,設 \(a_1,a_2,...a_n\) ,是 \(n\) 個非零整數,如果存在一個非零整數 \(d\), 使得 \(a_1\mid d,a_2\mid d,...a_n\mid d\) ,那么稱 \(d\) 是這 \(n\) 個數的公倍數。顯然存在無數多個公倍數,將這些公倍數中最小的一個記為 \(\text{lcm}(a_1,a_2,...a_n)\) ,即最小公倍數。

一個有意思的東西是: \(\gcd(x,y)\text{lcm}(x,y)=xy\)

擴展歐幾里得

如果您看了前面的內容,應該已經知道,擴歐(擴展歐幾里得算法簡稱擴歐,或者 \(exgcd\))是用來在已知 \(a,b\) 的時候,求解一組 \(p,q\) ,讓 \(pa+qb=\gcd(a,b)\)

首先由裴蜀定理,解一定存在。

因為 \(\gcd(a,b)=\gcd(b,a\bmod b)\)

所以 \(pa+qb=\gcd(b,a\bmod b)=pb+q*a\bmod b=pb+q*(a-a/b*b)=qa+(p-a/b*q)b\)

也就是說,\(p=q,q=p-a/b*b\) 意味着 \(p,q\) 改變,這是一個遞歸的轉移。

其本質是將 \(a\)\(b\) 的線性組合隨着歐幾里得算法的過程化簡為 \(b\)\(a\bmod b\) 的線性組合。

考慮遞歸邊界:也即是輾轉相除法的邊界 \(b=0\) ,顯然有 \(p=1,q=0\) ,回溯即可得到最原始的 \(p,q\)

int exgcd(int a,int b,int &x0,int &y0){//注意這里的引用
    if(b==0){//遞歸邊界
        x0=1;y0=0;
        return a;
    }
    int r=exgcd(b,a%b,x0,y0);//求gcd(a,b)
    int temp=y0;
    y0=x0-(a/b)*y0;
    x0=temp;     //回溯
    return r;
}

程序中求到的 \(x_0,y_0\) 僅僅是一組解,通解是:

\(\forall t\in\Z,x=x_0+\frac b{\gcd(a,b)}t,y=y_0-\frac a{\gcd(a,b)}t\)

其最小整數解 \(x\) 應在 \(t\)\(b\) 時。

參考

輾轉相除法的嚴格證明 https://zhuanlan.zhihu.com/p/155667184

\(\text{Luogu} 4549\) 【【模板】裴蜀定理】 https://aday526.blog.luogu.org/solution-p4549


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM