欧几里得算法 学习笔记

前言

本博客中所有的 有解 均指 有整数解
所有数如果不说明值域都是整数。

算法简介

为什么叫欧几里得算法呢?当然是欧几里得发明了啦
他能干什么呢?

  1. 求一个两个数字的最大公约数
  2. 求关于 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 并且 0r<b,显然 r=amodb
dadbd 就是 a,b 的公约数,
a=bq+rad=q×bd+rd
也就是 rd=adq×bd
因为 da,db,所以 ad,q×bd 都是整数,
所以 rd 也是整数,d 也是 b,amodb 的公约数,
同理我们也可以设 ebeamodb
同理可以证明 e 也是 a,b 的公约数。
换句话说, a,b 的公约数都是 b,amodb 的公约数,b,amodb 的公约数也都是 a,b 的公约数,
也就是说 a,bb,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 为斐波那契数列的相邻两项的时候,算法复杂度最坏。
这种做法又称为辗转相除法。

同时我们也发现以下几个结论(这些结论证明显然,这里就不写证明过程了):

  1. gcd(a,b,c)=gcd(gcd(a,b),c)
  2. lcm(a,b)×gcd(a,b)=a×b
  3. 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+by0bx1(amodb)y1=0
又因为 amodb=aab×b
所以 ax0+by0bx1(aab)×by1=0
展开得 ax0+by0bx1ay1+ab×by1=0
化简得 a(x0y1)+by0bx1+ab×by1=0
x0=y1,y0=x1ab×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=y0kagcd(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=ny0kagcd(a,b)

复杂度和前面的一样,是 O(log2max(a,b)).

应用

gcd除了求两个数字的最大公约数以外貌似我不知道其他功能,但是exgcd的功能非常强大。
这里只写我知道的吧...

  1. 求线性同余方程,因为 ax+by=c 等价于 axc(modb) ,这样可以得出在正整数范围内的 x 的最小值。
  2. 求逆元,因为 ax+by=1 等价于 ax1(modb) ,由于存在逆元 a1modb 所以 gcd(a,b)=1 ,也就是 ax+by=gcd(a,b)
  3. exCRT会用到。
posted @   jiangtaizhe001  阅读(99)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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工具
点击右上角即可分享
微信分享提示