1. 程式人生 > 實用技巧 >877. 擴充套件歐幾里得演算法

877. 擴充套件歐幾里得演算法

裴蜀定理

對於任意正整數a,b,一定存在一組正整數x和y,使得xa + yb = (a, b),並且(a, b)是a和b能湊(係數>0)出來的最小正整數。

為什麼是最小?

因為a和b的最大公約數是(a, b),所以xa + yb = k(a, b)必定成立,又因為k是整數, a, b, x, y > 0, 所以k >= 1, 所以(a, b)是xa + yb的最小值。

而裴蜀定理的證明可以用構造的方法來證明,即對於任意一個a, b都能找到x,y使得ax + by = (a, b),求x,y可以用擴充套件歐幾里得演算法求。

首先複習一下遞迴版歐幾里得演算法,求最大公約數的:

int gcd(int a, int b){
	if(b == 0) return a;
	if(a < b) return gcd(b, a);
	return gcd(b, a % b);
}

而擴充套件歐幾里得演算法就是要在求(a, b)的時候順便把x和y求出來。

過程:

\(xa + yb \\= gcd(a, b)\\=gcd(b, a \% b)\)

對於b和a % b,存在p和q使得

\(pb+q(a\%b) = gcd(b, a\%b)\)

由上式得\(pb+q(a\%b) = gcd(a, b)\)

\(gcd(a, b) = d\)

那麼\(xa + yb \\= pb + q(a \% b)\\=pb + q(a - \lfloor a/b\rfloor b)\\=qa+(p-q\lfloor a/b\rfloor)b\)

所以\(x = q\\y=p-q\lfloor a/b\rfloor\)

由此得到遞迴本層和下一層得關係

可得程式碼

int exgcd(int a, int b, int &x, int &y){
	if(b == 0){
		x = 1, y = 0;
		return a;
	}
	int d = exgcd(b, a % b, y, x);
	y -= a / b * x;
	
	return d;
}

這樣就同時得到了x,y和d,並且注意a對應得是x,b對應y,注意傳參順序。