擴充套件歐幾里得演算法(exgcd)
擴充套件歐幾里得演算法,是用來求形如
\[ax+by=c \]的不定方程的整數解的。
判斷是否有整數解
根據裴蜀定理,若 \(gcd(a,b) \mid c\),則一定有整數解,否則一定無解。
證明
設 \(d=gcd(a,b)\),顯然有 \(d \mid a,d \mid b\)。由於 \(x,y\) 都是整數,所以 \(d \mid (ax),d \mid (by)\)。
所以如果要讓式子成立,\(c\) 必須得是 \(a,b\) 的公約數的倍數才對。
又因為 \(x,y\) 是整數,所以 \(c\) 必須是 \(a,b\) 的最大公約數的倍數才行。
實在看不懂的話感性理解下吧awa
轉化
讓方程兩邊同除以 \(gcd(a,b)\),可以得到方程
\[a'x+b'y=c' \]其中
\[a'=a \times \frac{gcd(a,b)}{c},b'=b \times \frac{gcd(a,b)}{c},c'=c \times \frac{gcd(a,b)}{c}=gcd(a,b) \]後面求特解中提到的方程均為轉化後的方程,即後面方程中的 \(a\) 就是 \(a'\),\(b\) 就是 \(b'\)
求解
求特解
由歐幾里得演算法可知,\(gcd(a,b)=gcd(b,a \bmod b)\)
於是,我們可以得到
接下來我們就要根據 \(x',y'\) 來反推 \(x,y\)。
因為 \(gcd(a,b)=gcd(b,a \bmod b)\),所以
我們把右邊的式子變形一下:
\[bx'+(a \bmod b)y' \]\[=(a-b\left\lfloor\frac{a}{b}\right\rfloor)y'+bx' \]\[=ay'+bx'-b\left\lfloor\frac{a}{b}\right\rfloor y' \]\[= ay'+b(x'-\left\lfloor\frac{a}{b}\right\rfloor y') \]所以,\(x=y',y=x'-\left\lfloor\frac{a}{b}\right\rfloor y')\)
於是我們只要向歐幾里得演算法那樣遞迴,就能得到一組特解了。
但還有一個問題,就是遞迴邊界。
遞迴邊界顯然是 \(b=0\) 的情況,而此時的方程就變為: \[ax+by=ax=gcd(a,0)=a \]
所以此時 \(x=1\),\(y\) 是任意整數。
求解過程用程式碼寫出來就是這個亞子:
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;
y=0;//y可以是任意整數,這裡我們讓他等於0也可以
return a;
}
const ll m=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return m;
}
但是但是,這求的是
\[ax+by=gcd(a,b) \]的解呀。不是我們要的解。
因為我們在轉化時讓方程兩邊都除以 \(\frac{c}{gcd(a,b)}\),所以現在要乘回來:
求通解
這裡我們設之前求出來的通解為 \(x_0,y_0\)。
設 \(d=gcd(a,b)\)
則通解
\(x=x_0+\frac{b}{d} \times t,y=y0-\frac{a}{d} \times t\)
t是任意整數。
為什麼是這樣呢?
顯然我們需要滿足
把 \(x,y\) 拆開來:
\[a(x_0+n)+b(y_0-m)=c \]於是就有
\[an-bm=0 \]又因為 \(n,m\) 必須是整數,所以只有上面說的那個可以滿足要求了。
求最小正整數解
這裡指 \(x\) 是最小正整數。
當我們求出一組特解後,最小正整數解即
上面的式子用的是 C++ 語法。
求最小正整數解慣用手法,這裡不再累述。