当前位置: 首页 > news >正文

数论2:gcd、lcm与exgcd

gcd:Greatest Common Divisor,最大公约数,即对于不全为0的整数p、q,存在一最大的整数r,使得r|p、r|q且对于任意整数s,s|p且s|q,有r>=s。
记作gcd(p,q),特别的,gcd(a,0) = |a| (a!=0).
lcm:Least Common Multiple,最小公倍数,即对于两个非零整数p、q,存在一最小的整数r,使得p|r、q|r且对于任意整数s,p|s且q|s,有r<=s。
记作lcm(p,q),特别的,lcm(a,0) = 0.

一般通过欧几里得算法计算gcd(p,q),而lcm(p,q)通过p*q/gcd(p,q)得到。

下面介绍欧几里得算法(辗转相除法)

核心:gcd(a,b) = gcd(b,a%b).
证明:设a = b*k + c, 则 c = a % b.假设d是a、b的公约数,那么由c = a - b*k可得 c/d = a/d - b/d * k
因为d|a、d|b,a/d和b/d为整数,那么可知c/d也是整数,即d为a、b、c的公约数

反之假设d是b、c的公约数,那么由a = b*k + c可得 a/d = b/d * k + c/d,那么d也为a、b、c的公约数

故a,b的公约数等于b,a%b的公约数,那么自然有gcd(a,b) = gcd(b,a%b).

c++实现如下:

int gcd(int a, int b){if(b = 0) return abs(a);return gcd(b, a % b);
}

时间复杂度为O(log(max(a,b)))

int lcm(int a, int b){if(a == 0 || b == 0) return 0;return a * b / gcd(a, b);
}

视情况而定,有时候可能要用到高精度乘法(这里可以先计算a/gcd(a,b)或b/gcd(a,b)避免使用高精度除法)

更相减损术
对于大整数,取模运算耗时较长,这时候依据gcd(a, b) = gcd(min(a, b), max(a, b) - min(a, b))可以较快的找到最大公约数,但是要使用到高精度减法

对于多个数a1、a2……an的最大公约数,有:gcd(a1, a2, ……, an) = gcd(gcd(a1, a2, ……, an-1), an)的递归关系。
而lcm(a1, a2, ……, an) = a1a2……*an / gcd(a1, a2, ……,an)^(n-1)。

拓展欧几里得算法(exgcd)
拓展欧几里得算法用于求解一次线性方程ax+by=gcd(a,b)的解。
注意,对于方程ax+by=c,只有gcd(a,b)|c时,x,y才有整数解,即feishudingligcd:Greatest Common Divisor,最大公约数,即对于不全为0的整数p、q,存在一最大的整数r,使得r|p、r|q且对于任意整数s,s|p且s|q,有r>=s。
记作gcd(p,q),特别的,gcd(a,0) = |a| (a!=0).
lcm:Least Common Multiple,最小公倍数,即对于两个非零整数p、q,存在一最小的整数r,使得p|r、q|r且对于任意整数s,p|s且q|s,有r<=s。
记作lcm(p,q),特别的,lcm(a,0) = 0.

一般通过欧几里得算法计算gcd(p,q),而lcm(p,q)通过p*q/gcd(p,q)得到。

下面介绍欧几里得算法(辗转相除法)

核心:gcd(a,b) = gcd(b,a%b).
证明:设a = b*k + c, 则 c = a % b.假设d是a、b的公约数,那么由c = a - b*k可得 c/d = a/d - b/d * k
因为d|a、d|b,a/d和b/d为整数,那么可知c/d也是整数,即d为a、b、c的公约数

反之假设d是b、c的公约数,那么由a = b*k + c可得 a/d = b/d * k + c/d,那么d也为a、b、c的公约数

故a,b的公约数等于b,a%b的公约数,那么自然有gcd(a,b) = gcd(b,a%b).

c++实现如下:

int gcd(int a, int b){if(b = 0) return abs(a);return gcd(b, a % b);
}

时间复杂度为O(log(max(a,b)))

int lcm(int a, int b){if(a == 0 || b == 0) return 0;return a * b / gcd(a, b);
}

视情况而定,有时候可能要用到高精度乘法(这里可以先计算a/gcd(a,b)或b/gcd(a,b)避免使用高精度除法)

更相减损术
对于大整数,取模运算耗时较长,这时候依据gcd(a, b) = gcd(min(a, b), max(a, b) - min(a, b))可以较快的找到最大公约数,但是要使用到高精度减法

对于多个数a1、a2……an的最大公约数,有:gcd(a1, a2, ……, an) = gcd(gcd(a1, a2, ……, an-1), an)的递归关系。
而lcm(a1, a2, ……, an) = a1a2……*an / gcd(a1, a2, ……,an)^(n-1)。

拓展欧几里得算法(exgcd)
拓展欧几里得算法用于求解一次线性方程ax+by=gcd(a,b)的解。
注意,对于方程ax+by=c,只有gcd(a,b)|c时,x,y才有整数解,即裴蜀定理

下面讲解exgcd如何求出ax+by=gcd(a,b)ax+by=c(gcd(a,b)|c)的特解与通解。

我们知道,gcd(a,b) = gcd(b, a%b), 则有ax + by = bx' + (a%b)y',将a%b代换为a- a/b * b(注意此处的a/b是整除

展开可得ax + by = bx' + ay' - (a/b * b)y'
整理得x = y', y = x' - a/b*y'

由此设计exgcd算法,可以在得到gcd(a,b)的同时算出x、y的一组特解
特别的,当b = 0时,gcd(a, b) = a(a>0), x = 1, y = 0;

故有如下exgcd代码:

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

这时得到一组特解(x0, y0)与g = gcd(a, b, x, y),而其通解为
x=x0+k*(b/g)
y=y0-k*(a/g)

x的最小非负值为(x%(b/g) + (b/g)) % (b/g),x为任意一组解的x;
y的最小非负值为(y%(a/g) + (a/g)) % (a/g),a为任意一组解的y;
注意,此处的两个最小非负值一般不同时取到,除非只有一个k对应唯一一组非负解(非负解:x、y均非负的一组解)。

若要求非负解是否存在,可从x>0与y>0这个方程组中,k整数解的情况判断,同时还能得知x、y的最大/最小非负值。P5656 【模板】二元一次不定方程 (exgcd)

一般在确定gcd(a,b)|c后,可以直接对ax+by=c使用exgcd,就能通过相似的过程得到解,但是要乘上c/d(d = gcd(a,b))来缩放x与y。原因在于,当c=k*d时,实际运算的式子是ax'+by'=gcd(a,b),算出来的式子与目标式子左右少一个c/d的系数。

关于ax+by=c的整数解,还有如下推导:
d=gcd(a,b),c=k*d,必有整数a'、b'满足a'd = ab'd = b,那么有a'dx + b'dy = kd,即a'x + b'y = k,其中gcd(a', b')=1,即a'与b'互质。

那么我们可以考虑对方程a'x + b'y = 1使用exgcd算法,那么就可以得到x,y的特解与通解。

exgcd算法有着广泛的应用,如求模逆元。

http://www.jsqmd.com/news/264101/

相关文章:

  • 计算机小程序毕设实战-基于SpringBoot+Vue的高校学科竞赛管理系统微信小程序基于springboot+微信小程序的院竞赛管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • day144—递归—平衡二叉树(LeetCode-110)
  • 2026年市场可靠的活性炭箱优质厂家哪家靠谱,滤筒除尘器/旋风除尘器/活性炭箱/催化燃烧,活性炭箱生产商口碑排行 - 品牌推荐师
  • STM32单片机分享:智能鱼缸系统
  • 2026年国内可靠的活性炭箱制造厂家推荐排行榜,RTO/旋风除尘器/沸石转轮一体机/除尘器,活性炭箱公司推荐榜 - 品牌推荐师
  • 交通仿真软件:VISSIM_(22).交通仿真在城市规划中的应用
  • STM32单片机分享:智能书桌系统
  • day145—递归—二叉树的右视图(LeetCode-199)
  • 理性选择RTO:基于用户反馈的供货商横向评测,沸石转轮/活性炭箱/RTO/沸石转轮一体机,RTO源头厂家排行榜 - 品牌推荐师
  • 小程序计算机毕设之基于微信小程序的大学生科技竞赛管理系统的设计与实现基于springboot+微信小程序的院竞赛管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 2026苏州新房装修大揭秘:这些服务优质的公司你不能错过! - 品牌测评鉴赏家
  • Flink Elasticsearch Connector 从 0 到 1 搭一个高吞吐、可容错的 ES Sink
  • Flink Firehose Sink 把实时流数据稳定写进 Amazon Kinesis Data Firehose
  • GESP认证C++编程真题解析 | 202309 五级
  • vscode的.vscode文件记录
  • 人工智能之数据分析 Pandas:第九章 性能优化 - 实践
  • 2026年国内最好的沸石转轮+CO定制厂家口碑推荐榜单,除尘器/沸石转轮一体机/滤筒除尘器/催化燃烧,沸石转轮生产商排名 - 品牌推荐师
  • 小程序毕设项目:基于springboot+微信小程序的院竞赛管理系统(源码+文档,讲解、调试运行,定制等)
  • 开发智力的课堂
  • 详细介绍:法律大模型微调:基于 LLaMA-Factory 的指令微调方案
  • 【毕业设计】基于springboot+微信小程序的院竞赛管理系统(源码+文档+远程调试,全bao定制等)
  • 2026年国内知名的活性炭箱供应厂家联系方式,RTO/旋风除尘器/催化燃烧/活性炭箱/滤筒除尘器,活性炭箱品牌怎么选择 - 品牌推荐师
  • 2026苏州厂房装修大揭秘:这几家公司不容错过! - 品牌测评鉴赏家
  • 2026极简风爱好者必看!这些宝藏装修公司绝了 - 品牌测评鉴赏家
  • 苏州装修宝藏公司大盘点,口碑爆棚不踩雷! - 品牌测评鉴赏家
  • GESP认证C++编程真题解析 | 202309 六级
  • 第一、二、三章 习题总结
  • 人群仿真软件:AnyLogic_(4).行人库功能详解
  • GESP认证C++编程真题解析 | 202306 一级
  • 提示工程架构师必学:用Few-shot Learning增强提示情境感知的AI技巧