擴充套件歐幾里得演算法筆記

2022-09-10 19:12:14 字數 1684 閱讀 4429

在學習擴歐之前,我們首先要了解下面這兩個部分的知識。給定數 \(a,b\), 求 \(gcd(a,b)\)。

也就是說,對於數 \(a,b\), \(gcd(a,b)=gcd(b,a \%b)\)

對於歐幾里得演算法,也比較好用遞迴實現。

c++**如下

int gcd(int a,int b)
若\(a,b\)是整數,且\(gcd(a,b)=d\),那麼對於任意的整數 \(x,y\),\(ax+by\) 都一定是\(d\)的倍數,特別地,一定存在整數\(x,y\),使 \(ax+by=d\)成立。

下面,可以正式進入對擴充套件歐幾里得演算法的學習了

首先,由於裴蜀定理,我們知道 \(ax+by=gcd(a,b)\) 一定存在,而擴充套件歐幾里得演算法,就是為了求出題中的\(x,y\)。

而當我們的歐幾里得演算法執行到最後一步,也就是 \(b=0\) 時,此時的 \(gcd(a,b)=a\),那麼很明顯 \(ax+by=gcd(a,b)\) 的解為 \(x=1,y=0\)。

既然知道了最後一層,那我們就可以層層遞推出第一層了(一開口就知道老千層餅了)。 但是要如何實現呢?

首先我們知道:\(a\%b=a-(a/b)*b\)(注意此處的"/"捨去餘數);代入:

\(b*x_1 + (a-(a/b)*b)*y_1\)

\(= b*x_1 + a*y_1 – (a/b)*b*y_1\)

\(= a*y_1+ b*(x_1 – a/b*y_1) = gcd\) 發現 \(x_0 = y_1 , y_0 = x_1 – a/b*y1\)

引用自此處

然後,我們就可以愉快的寫**了

**如下

int x,y,gcd;

void exgcd(int a, int b)

exgcd(b,a%b);//遞迴

int t=y;//遞迴返回後執行

y=x-(a/b)*y;

x=t;

}

至此,對於擴歐的學習就結束了。

讓我們來看這樣一道題

洛谷p1082 同餘方程

求關於\(x\)的同餘方程 \(ax≡1(modb)\) 的最小正整數解。

對於 100%的資料,&2 ≤a, b≤ 2,000,000,0002≤a,b≤2,000,000,000&。

輸入格式

一行,包含兩個正整數 a,ba,b,用乙個空格隔開。

輸出格式

乙個正整數 x_0,即最小正整數解。輸入資料保證一定有解。

由於 \(a≥2\),將上面式子化簡後我們可以得到 \(ax-by=1\)
#includeusing namespace std;

int x,y;

void exgcd(int a, int b)

exgcd(b,a%b);

int t=y;

y=x-(a/b)*y;

x=t;

}int main()

這裡有個值得注意的地方,就是 \((x+b)\%b\)。

因為題中要求的是最小正整數,所以先加,保證為正數,後取餘,保證為最小。

擴充套件歐幾里得演算法

includeusing namespace std typedef struct nodenode node t node extend euclid int a,int b else extend euclid b,a b int tmp t.x t.x t.y t.y tmp a b t.y ...

擴充套件歐幾里得演算法分析詳細

如果a,b兩數是整數,那麼一定存在整數x,y 使得 ax by bcd a,b int bcd int a,int b 這個演算法很好理解,如果實在看不懂,用筆紙帶入兩個數相信你能懂 代入數字加深理解 求 50,35 50 1 35 15 15 50 1 35 35 15 2 5 5 35 15 2...

歐幾里得演算法

歐幾里得演算法中,計算 x,y 的最大公約數的方法是輾轉相除,例如 26,15 26 15 1 11 15 11 1 4 11 4 2 3 4 3 1 1 3 1 3 0 可知,26,15 1 如果 x,y r,那麼有 ax by r,可以看出,上面的步驟實際上是可以直接得出 a,b 的 26 15...