首先了解一下欧几里得算法,即辗转相除法
如果我们要求1997和615两个数的最大公约数
1997 / 615 = 3 ...... 152
615 / 152 = 4 ...... 7
152 / 7 = 21 ...... 5
7 / 5 = 1 ...... 2
5 / 2 = 2 ...... 1
2 / 1 = 2 ...... 0
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。(摘自百度百科)
设a为被除数,b为除数,由上面容易得到 gcd( a , b ) == gcd( b , a%b ),可得到程序:
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b , a%b);
}
那么扩展欧几里得算法,究竟扩展了哪里?
欧几里得算法仅求出gcd(a,b),而扩展欧几里得算法求出了一对x,y,其中ax+by=gcd(a,b)
这个等式一定成立(裴蜀定理:若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。)
收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。
(扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足裴蜀等式 ax+by=gcd(a,b)
如果a是负数,可以把问题转化成 |a| (-x) + by = gcd( |a| , b ),然后令x'=(-x)。(摘自百度百科) )
首先,这个方程一定是有多解的,我们只需求出其中一组特解x1、y1即可表示出通解
设有
按照以上方程形式同样有:
由欧几里得定理有:
带入得到:
而
得到:
展开后对比系数可得到结果
我们知道,当欧几里得算法到达边界时,
那么边界条件就是对a∗x1+b∗y1=a求解 , 很显然,此时x1=1,y1=0
int exgcd(int a,int b,int &x1,int &y1)
{
if(b==0)
{
x1=1;
y1=0;
return a;
}
int x2,y2;
int d=exgcd(b,a%b,x2,y2);
x1=y2;
y1=x2-(a/b)*y2;
return d;
}