一、欧几里得算法(辗转相除法):
结论:gcd(a,b)=gcd(b,a%b)。
证明:假设a,b的最大公约数为r,a=k1r,b=k2r(k1>k2)。
则a%b=k1r-nk2r=(k1-nk2)r。下面要证k2和(k1-nk2)互质,利用反证法:假设k2=x1d,(k1-nk2)=x2d,则k1=x2d+nk2=x2d+nx1d。显然与k2,k1互质,与假设矛盾,证明k2和(k1-nk2)互质,原式得证。下面利用递归思想实现,递归的边界即为b==0,返回a。
代码如下:
int gcd(int a,int b){
if(b==0)return a;
else return (b,a%b);
}
二、拓展欧几里得算法
1、前置知识:裴蜀定理
结论:若a,b,x,y是整数,且gcd(a,b)=d,则ax,by,ax+by一定为d的倍数,且ax+by=gcd(a,b)一定有整数解。并且对于方程ax+by=z,d|z一定存在整数解否则无整数解。
2、拓展欧几里得算法是干什么的?
用来求形如ax+by=gcd(a,b)的一组解
3.算法
ax+by=gcd(a,b),若b==0,则gcd(a,b)=a,x=1。若b不等于0,则考虑gcd(a,b)=gcd(b,a%b)。ax+by=gcd(a,b)等价于去递归求解
bx+(a%b)y=gcd(b,a%b)。则bx+(a-[a/b]b)y=gcd(b,a%b)。
则bx+ay-b[a/b]y=gcd(b,a%b)。则ay+b*(x-[a/b]*y)=gcd(b,a%b)
所以一个解即为x=y,y=x-[a/b]*y。
4.代码
void exgcd(int &x,int &y,int a,int b){
if(!b){
x=1;y=0;return;
}
exgcd(x,y,b,a%b);
int t=x;x=y;y=t-a/b*y;
}