扩展欧几里得算法主要用来解决这样一个问题:给定两个非零的整数a、b,求ax + by = gcd(a,b)的整数解,其中gcd(a,b)表示a和b的最大公约数。
通常谈到最大公约数时,我们都会提到一个非常基本的事实:
给予二个整数a、b,必存在整数x、y使得ax + by = gcd(a,b)。
如何求出ax + by = gcd(a,b)的整数解呢?
1、当b == 0时
毫无疑问gcd(a,b) == a,此时存在解x = 1,y = 0;
2、当a和b均不为0时
要求ax + by = gcd(a,b)的解,根据欧几里得算法(辗转相除法)可知gcd(a,b) = gcd(b,a%b)
而bx' + (a%b)y' = gcd(b,a%b),则
ax + by = bx' + (a%b)y'
ax + by = bx' + (a - a/b * b)y' (此处a/b为整除,即只保留整数部分)
ax + by = ay' + b(x' - a/b * y')
对比系数可得
x = y',y = x' - a/b*y'
也就是说如果我们知道了x',y'就可以倒推得到x,y
根据欧几里得算法(辗转相除法)可知,经gcd(a,b) = gcd(b,a%b)如此反复,最终b将变为0,得到1中所描述的情况。此时,利用b为0时的解x = 1,y = 0往前逐步倒推,即可得到最终ax + by = gcd(a,b)的一组整数解。
int exGcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int g = exGcd(b, a % b, x, y);
int temp = x;
x = y;
y = temp - a / b * y;
return g;
}
如何根据已经求得的一组整数解求得其他的整数解呢?
我们设新的解x' = x + s1,y' = y - s2,则有a(x + s1) + b(y - s2) = gcd(a,b),化简可得as1 = bs2,即a/b = s2/s1
让a,b同时除以一个较大的数(即a和b的最大公约数)
, (k为任意整数)
由此可以得到ax + by = gcd(a,b)解的公式
(x0、y0为扩展欧几里得算法所求得的一组解)