1. 程式人生 > 其它 >拓展歐幾里得

拓展歐幾里得

在瞭解拓展歐幾里得時,建議大家先去看一眼歐幾里得演算法(也叫輾轉相除法

過程大概如下圖所示:

那麼,我們因此也可以給出一段程式碼:

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;
}

後續的證明正在施工中。