扩展欧几里德
扩展欧几里德是解形如的一种算法。
1.利用欧几里德算法(更相减损术)得出gcd(x,y)。
比如求gcd(21,175)
175%21=7;
21%7=0;
所以gcd(21,175)=7;
int gcd(int a,int b)//欧几里德求gcd(a,b)
{
if(b==0)
return a;
else
{
int c=a;
a=b;
b=b%c;
return gcd(a,b);
}
}
对于高精度gcd()可以有个优化:
假定a>b :
gcd(a,b)=gcd(a/2,b) if(a%2==0&&b&1)
=gcd(a,b/2) if(b%2==0&&a&1)
=2gcd(a/2,b/2) if(!(a&1)&&!(b&1))
=gcd(b,a-b) else
2. 扩展欧几里德基本算法:
对于两个不完全为0的非负整数a,b,必然存在x,y使得 gcd(a,b)=ax+by
证明:
1.b=0 时,显然成立(x=1)
2.b!=0 时,设a>b
ax1+by1=gcd(a,b);
bx2+(a mod b)y2=gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b)=gcd(b,a mod b);
则:ax1+by1=bx2+(a mod b)y2;
即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;
根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
int exgcd(int a,int b,int &x,int &y)//扩展欧几里德
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return r;
}