在我们学习扩展欧几里得算法(下面简称扩欧)之前呢,我们先了解一下什么是欧几里得算法,当然很多人之前应该都接触过,但是还是讲一下吧,所谓欧几里得算法,就是 (也叫辗转相除法),当我们求两个数的最大公约数的时候, 毫无疑问是最优的算法。
下面给出欧几里得的算法公式以及相应的代码:
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
那我们现在开始正式讲扩欧,我们给出一个线性组合
当我们需要去求解这个表达式的
的值是,就要用到扩欧了。
下面给点定理:
定理:如果
和
都是整数,则有整数
和
使得
。
我们可以得出一个推论:整数
和
互素当且仅当存在整数
和
使得
对于不定方程 ,如果 不是 的倍数,则不定方程无解,否则用扩欧的算法进行求解。
下面我们给出扩展欧几里得算法的模板:
int ex_gcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int d = ex_gcd(b, a % b, x, y);
int t;
t = x;
x = y;
y = t - a / b * y;
return d;
}
各大OJ网站上的用到扩欧算法的试题:
2141, 2773
3593