拓展歐幾里得
阿新 • • 發佈:2022-05-16
在瞭解拓展歐幾里得時,建議大家先去看一眼歐幾里得演算法(也叫輾轉相除法)
過程大概如下圖所示:
那麼,我們因此也可以給出一段程式碼:
int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a;
}
為什麼成立這一塊以後會來填坑的/qq
那麼,什麼是拓展歐幾里得呢?
拓展歐幾里得是一種演算法,在不斷的輾轉相除中得到不定方程
\(ax+by=c\) 的一組解;
我們藉著上面的那個圖來說明一下:
我們看最後一個式子:\(21=6×3+3\) 這裡,我們也可以寫成:\(3=6×(-3)+21\)
也就是說,\(3\) 可以被表示為 \(6\) 和 \(21\)
那麼我們接著看,\(6\) 也可以成 \(21\) 和 \(27\) 的線性組合,因此,有:
\[3=6×(-3)+21=(27-21)×(-3)+21=27×(-3)+21×4 \]那麼一直往下推,我們就可以推出來:\(3\) 就是 \(75\) 和 \(48\) 的線性組合;
那麼,如果 \(c\) 是其他的數,能不能找到解呢?
其實 \(c\) 必須要是 \(\gcd(a,b)\) 的倍數,因此,嘗試等式兩邊同時初以 \(\gcd(a,b)\);
\[\frac{a}{\gcd(a,b)}x+\frac{b}{\gcd(a,b)}y=\frac{c}{\gcd(a,b)} \]因為等式的左側肯定是一個整數
那麼我們同樣也來看一看這個的具體過程
這裡呢,通過求 \(bx_0+(a \mod b)y_0=c\) 的解,就可以得出來 \(ax+by=c\) 的解;
對比 \(x\) 的係數和 \(y\) 的係數,就是
\(\begin{cases}x=y0\\y=x0-\left [ a /b \right ]y0 \end{cases}\)
這玩意其實就跟輾轉相除差不多一回事,當 \(b=0\) 的時候結束遞迴,
最後令 \(x=1,y=0\)
int gcd(int a, int b,int &x,int &y) { if (b == 0) { x = 1, y = 0; return a; } int ans = gcd(b, a % b, x, y); int temp = x; x = y; y = temp - a / b * y; return ans; }
後續的證明正在施工中。