1.3 GCD、EXGCD、线性同余方程

1.3 GCD、EXGCD、线性同余方程

最大公约数(GCD)和最小公倍数(LCM)的基本概念也是小学知识。对于任意整数 a , b a,b a,b,我们有一个很重要的公式,即 a ∗ b = G C D ( a , b ) ∗ L C M ( a , b ) a*b = GCD(a,b)*LCM(a,b) ab=GCD(a,b)LCM(a,b)

首先我们会介绍几种基本的求GCD方式,虽然C++选手完全可以使用__gcd()函数去求,但自定义的求法往往更加灵活,方便优化以及改动实现其他功能。

辗转相除法求GCD

辗转相除法又称欧几里得算法,其原理是 G C D ( x , y ) = G C D ( x , y − x ) GCD(x,y)=GCD(x,y-x) GCD(x,y)=GCD(x,yx),证明如下:

①设 z ∣ x z|x zx z ∣ y z|y zy,则 z ∣ ( y − x ) z|(y-x) z(yx)

②设 z z z不是 x x x因子,则 z z z不是 x x x y − x y-x yx的公因子。

③设 z ∣ x z|x zx z z z不是 y y y的因子,则 z z z不是 x x x y − x y-x yx的公因子。

当然我们可以把这个转换为模运算,因为取 y − x y-x yx的前提是 y > x y>x y>x,于是我们可以递归的用模运算去实现,保证函数的第一个参数大于第二个参数(实在理解不了可以记模板)。代码如下。

typedef long long ll;
ll GCD(ll x, ll y) {
   
    return y == 0 ? x : GCD(y,x % y);
}

二进制算法求GCD

这个算法比辗转相除法更快一点点,但这个优化是常数级别的。原理是通过不断去除因子2来降低常数。具体做法如下:

x = y x=y x=y,则 G C D ( x , y ) = x GCD(x,y)=x GCD(x,y)=x,否则:

①若 x , y x,y

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值