许多部分内容百度百科
GCD
定义
欧几里德算法又称辗转相除法,是指用于计算两个正整数a,b的最大公约数。
结论与证明
对于a,b两个正整数(a>b),
gcd(a,b)=gcd(a,a mod b)
。
gcd(a,b)
即为a与b的最大公约数。
下面给出证明:
设
a=kb+r
,d是a,b的一个公约数。
∵r=a−kb
,两边同时除以d得
r/d=a/d−kb/d=m
易得m为整数。
∴r=md
,即d也是r的一个约数。
所以a,b与b,a%b的公约数是一样的。
因此
gcd(a,b)=gcd(b,a mod b)
。
证毕。
代码:
求GCD可以递归实现
int gcd(int x,int y){
if (y==0) return x;
return gcd(y,x%y);
}
应用
欧几里得算法可以在很短的时间内算出两个正整数的最大公约数。具体多短,参考拉梅定理。
扩展GCD
定义
扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by=gcd(a, b)=d。
实现与证明
设a>b≥0。
当b=0时,显然gcd(a,b)=a。此时x=1,y=0。
当b>0时,
设
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
。
根据
a mod b=a−[a/b]
,展开后合并同类项得:
ax1+by1=ay2+b(x2−[a/b]y2)
。
根据恒等式定理得
x1=y2,y1=x2−[a/b]y2
。
可以发现x和y均可以从上一得到。
而最初状态即为x=1y=0。
因此它也可以递归实现
代码
EXGCD在求值的同时也可以顺带出gcd(a,b)。
int exgcd(int a,int &x,int b,int &y){
if (b==0){
x=1; y=0; return a;
}
int r=exgcd(b,x,a%b,y);
int k=x; x=y; y=k-a/b*y;
return r;
}