hdu java大整数gcd_GCD、LCM --算法竞赛专题解析(20)

本系列文章将于2021年整理出版。前驱教材:《算法竞赛入门到进阶》 清华大学出版社

网购:京东 当当   做者签名书:点我

公众号同步:算法专辑

暑假福利:胡说三国

有建议请加QQ 群:567554289html

最大公约数java

1. GCD定义

整数a和b的最大公因数是指能同时整除a和b的最大整数,记为gcd(a, b)。

例如:gcd(15, 81) = 3,gcd(0, 44) = 44,gcd(0, 0) = 0,gcd(-6, -15) = 3,gcd(-17,289) = 17。

注意:因为-a的因子和a的因子相同,所以gcd(a, b) = gcd(|a|, |b|)。编码时只须要关注正整数的最大公因数。c++

2. GCD性质

(1)gcd(a,b) = gcd(a, a+b) = gcd(a, ka+b)

(2)gcd(ka, kb) = k·gcd(a, b)

(3)定义多个整数的最大公约数:gcd(a, b, c) = gcd(gcd(a, b), c)

(4)若gcd(a, b) = d,则gcd(a/d, b/d) = 1,即a/d与b/d互素。这个定理很重要。

(5)gcd(a+cb, b) = gcd(a, b)web

3. GCD编码

编程时能够直接用c++函数std::__gcd(a, b)。注意:参数a和b都应该是正整数,不然可能会返回负数。下面介绍三种算法。算法

3.1 欧几里得算法

用展转相除法求gcd,即gcd(a, b) = gcd(b, a mod b)。代码是:编程

int gcd(int a, int b){ // 通常要求a>=0, b>0。若a=b=0,代码也正确,返回0

return b? gcd(b, a%b):a;

}

这是竞赛中最经常使用的编码,它极为高效,“拉梅定理”给出了复杂度分析。

拉梅定理:用欧几里得算法计算两个正整数的最大公因数,须要的除法次数不会超过两个整数中较小的哪一个十进制数的位数的5倍。

推论:用欧几里得算法求gcd(a, b),a > b,须要O

(

(

l

o

g

2

a

)

3

)

O((log_2a)^3)O((log2​a)3)次位运算。

欧几里得算法的缺点是须要作除法取模运算,而高精度大数的除法比较耗时,此时能够用“更相减损术”app

不过,在竞赛中不太可能直接使用“更相减损术”和stein算法求最大公约数。下面的介绍,只是为了帮助读者理解GCD的性质。ide

3.2 更相减损术

计算基于这一性质:gcd(a, b) = gcd(b, a-b) = gcd(a, a-b)。svg

计算步骤:用较大的数减较小的数,把所得的差与较小的数比较,而后继续作减法操做,直到减数和差相等为止。

编码也很简单:函数

int gcd(int a, int b){

while(a != b){ //a==b时结束计算

if(a > b) a = a - b;

else b = b - a;

}

return a;

}

更相减损术虽然避免了欧几里得的取模计算,可是计算次数比欧几里得算法多不少,极端状况下须要计算O

(

m

a

x

(

a

,

b

)

)

O(max(a, b))O(max(a,b))次,例如a = 100,b = 1时,需计算100次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值