最近学习了拓展欧几里得算法,写下来,加深理解,备忘;
在讲拓展欧几里得算法前,先要了解一下裴蜀定理(贝祖定理);
这个定理讲的是
1、若a,b为整数,gcd(a,b)=d;那么对于任意x,y,ax+by一定是d的倍数,即(ax+by)%d=0;
2、一定存在x,y,使得ax+by=d;
拓展欧几里得算法正是求解其中x,y的一种算法;
拓展欧几里得算法:
目的:给定两个不同时为零的整数a,b,计算gcd(a,b),以及整数x和y,使得ax+by=gcd(a,b);
typedef long long int64;
int64 gcd_ex(int64 a, int64 b,int64& x, int64& y)
其中返回的是gcd(a,b);
程序代码:
typedef long long int64;
int64 gcd_ex(int64 a, int64 b,int64& x, int64& y)
{
if (b == 0) { x = 1; y = 0; return a; }
int64 d = gcd_ex(b, a % b, y, x););//前半部分和欧几里得算法是一样的;
y = y - a / b * x;//这边赋值和上面交换x,y的原因,百度百科讲的挺好的
return d;
}
原因如下:
a>b>0 时
设 ax
1+ by
1= gcd(a,b);
bx
2+ (a mod b)y
2= gcd(b,a mod b);
根据朴素的欧几里得公式有 gcd(a,b) = gcd(b,a mod b);
则:ax
1+ by
1= bx
2+ (a mod b)y
2;
即:ax
1+ by
1= bx
2+ (a - [a / b] * b)y
2=ay
2+ bx
2- [a / b] * by
2;
也就是ax
1+ by1 == ay
2+ b(x
2- [a / b] *y
2);
根据恒等定理得:x
1=y
2; y
1=x
2- [a / b] *y
2;