gcd及扩展gcd

欧几里德算法gcd

概述

该算法即经典算法辗转相除法,假设a,b(a>b)的最大公约数为gcd(a,b),辗转相除法的内容就是:gcd(a,b)=gcd(b,a%b)(边界gcd(k,0)=k)。

证明

(看完百度百科后写的=_=,非常像,百度百科原版证明可以见此链接http://baike.baidu.com/view/255668.htm
设c=gcd(a,b),a=mc,b=nc,r=a%b,则可设r=a-kb
∴r=a-kb=mc-kb=mc-knc=(m-kn)c
∴r是c的因数
∵n与m-kn互质(假设n与m-kn不互质,则可设m-kn=xd,n=yd(d>1),那么m=xd+kn=xd+kyd=(x+ky)d,n=yd,则a=(x+ky)cd,b=ycd,那么a,b的一个公共因子就是cd,而cd>c,与题设不符,所以n与m-kn互质)
∴gcd(b,r)=c
∴gcd(a,b)=gcd(b,r)
特殊:当r=0时,显然b是a的因子,gcd(a,b)=gcd(b,0)=b,正确。
ps:当a<=b时,此公式仍然适用,请读者独立思考~

代码

int gcd(int a,int b) {if (b) return gcd(b,a%b); else return a;}

效率

不难得出,每次a至少/2(或者a,b交换),所以效率为log2(a)
ps:处理次数最多的是斐波那契数列的相邻两个,因为斐波那契数列相邻两个数f[i-1],f[i]每次处理过后变成了f[i-2],f[i-1]。

扩展欧几里德算法exgcd

概述

对于一个方程ax+by=(a,b)(gcd(a,b)可简写为(a,b),a>b),求任意一组x,y。扩展欧几里得算法可以快速求解x和y。

方法

首先我们知道gcd(a,0)=a,此时x=1,y可以为任何数(一般给0)。根据欧几里得算法,我们可以得到:
bX+(a%b)Y=(b,a%b)=(a,b)(假设X和Y已经求出了)
联立一下:ax+by=bX+(a%b)Y
因为a%b=a-b*(a div b)(注:div表示整除以,也就是编程中的)
所以ax+by=bX+aY-b*(a div b)*Y
移项,可得a(x-Y)=b(X-y-(a div b)*Y)
那么只要两边=0,就可以得到一组解:
x-Y=0
X-y-(a div b)*b*Y=0
即x=Y,y=X-(a div b)*Y

那么只要递归处理就行了。
ps:不难发现,得到一组解x0,y0之后,可以推出所有解:
x=x0+k*b/(a,b)
y=y0-k*a/(a,b)
k∈Z

代码

int exgcd(int a,int b,int &x,int &y)
{
    if (!b) {x=1;y=0;return a;}
    int r=exgcd(b,a%b,x,y),t=x;x=y;y=t-a/b*y;
    return r;
}

效率

和gcd效率一样。

运用

有了扩展欧几里得算法,就可以快速求解乘法逆元和模方程了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值