前言
本博客中所有的 有解
均指 有整数解
。
所有数如果不说明值域都是整数。
算法简介
为什么叫欧几里得算法呢?当然是欧几里得发明了啦
他能干什么呢?
- 求一个两个数字的最大公约数
- 求关于 x,y 的二元一次不定方程 ax+by=gcd(a,b) 的整数解
求最大公约数(gcd)
最大公约数即为 Greatest Common Divisor,常缩写为 gcd 。
一组数的公约数,是指同时是这组数中每一个数的约数的数。而最大公约数,则是指所有公约数里面最大的一个。
我们一般用 gcd(a,b) 或者 (a,b) 来表示两个数字的最大公约数。
我们一般用 lcm(a,b) 或者 [a,b] 来表示两个数字的最小公倍数(Least Common Multiple, LCM)。
显然 gcd(a,b)=gcd(b,amodb)
证明如下:
设 a=bq+r 并且 0≤r<b,显然 r=amodb,
设 d∣a 且 d∣b,d 就是 a,b 的公约数,
由 a=bq+r 得 ad=q×bd+rd,
也就是 rd=ad−q×bd
因为 d∣a,d∣b,所以 ad,q×bd 都是整数,
所以 rd 也是整数,d 也是 b,amodb 的公约数,
同理我们也可以设 e∣b 且 e∣amodb,
同理可以证明 e 也是 a,b 的公约数。
换句话说, a,b 的公约数都是 b,amodb 的公约数,b,amodb 的公约数也都是 a,b 的公约数,
也就是说 a,b 和 b,amodb 的公约数都相同,那么它们的最大公约数也都相等,也就是 gcd(a,b)=gcd(b,amodb)
代码
| int gcd(int x,int y){ |
| if(x%y==0) return y; |
| return gcd(x%y,y); |
| } |
从递归式不难得出复杂度为 O(log2max(a,b)) ,并且当 a,b 为斐波那契数列的相邻两项的时候,算法复杂度最坏。
这种做法又称为辗转相除法。
同时我们也发现以下几个结论(这些结论证明显然,这里就不写证明过程了):
- gcd(a,b,c)=gcd(gcd(a,b),c)
- lcm(a,b)×gcd(a,b)=a×b
- lcm(a,b,c)=lcm(lcm(a,b),c)
这样我们就可以求出多个数的最大公约数以及单个数、多个数的最小公倍数了。
求二元一次不定方程的整数解(exgcd)
根据裴蜀定理,我们知道,关于 x,y 的二元一次不定方程 ax+by=gcd(a,b) 有整数解。
证明略,我不会你自己看。
我们可以模仿计算最大公约数的方法来解这个方程。
假设有一个方程 ax0+by0=gcd(a,b)
我们通过一次辗转相除,得到 bx1+(amodb)y1=gcd(a,b)
两式相减,得: ax0+by0−bx1−(amodb)y1=0
又因为 amodb=a−⌊ab⌋×b
所以 ax0+by0−bx1−(a−⌊ab⌋)×by1=0
展开得 ax0+by0−bx1−ay1+⌊ab⌋×by1=0
化简得 a(x0−y1)+by0−bx1+⌊ab⌋×by1=0
即 x0=y1,y0=x1−⌊ab⌋×y1
递归边界就是 b=0 ,此时返回 x=1,y=0 即可。
代码:
| void exgcd(int a,int b,int &x,int &y){ |
| if(!b){ x=1; y=0; return; } |
| exgcd(b,a%b,x,y); |
| int t=x; |
| x=y; |
| y=t-(a/b)*y; |
| return; |
| } |
根据得到的两个解 x=x0,y=y0 ,我们就可以得到这个方程的所有整数解:
x=x0+kbgcd(a,b)
y=y0−kagcd(a,b)
显然这里的 k 是整数。
那么对于任意关于 x,y 方程 ax+by=c 该怎么解呢?
首先通过裴蜀定理判断它有没有解,如果有解那么肯定 gcd(a,b)|c ,不妨设 c=ngcd(a,b)
我们先解方程 ax+by=gcd(a,b) ,得到一个解 x=x0,y=y0
不难发现原方程也有一个解 x=nx0,y=ny0
解即为
x=nx0+kbgcd(a,b)
y=ny0−kagcd(a,b)
复杂度和前面的一样,是 O(log2max(a,b)).
应用
gcd除了求两个数字的最大公约数以外貌似我不知道其他功能,但是exgcd的功能非常强大。
这里只写我知道的吧...
- 求线性同余方程,因为 ax+by=c 等价于 ax≡c(modb) ,这样可以得出在正整数范围内的 x 的最小值。
- 求逆元,因为 ax+by=1 等价于 ax≡1(modb) ,由于存在逆元 a−1modb 所以 gcd(a,b)=1 ,也就是 ax+by=gcd(a,b) 。
- exCRT会用到。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具