「学习笔记」极度精简好理解的exgcd

「学习笔记」极度精简好理解的exgcd

前言

本文通过尽量短,通俗易懂的形式帮助大家理解最简单的 exgcd。

前置知识:

裴蜀定理:

ax+by=c,xZ,yZgcd(a,b)|c

欧几里得算法(辗转相除法)

gcd(a,b)=gcd(b,amodb)   (b0)

模运算的本质:

amodb=aabb

其中 ab 指的是 ab 下取整。

正片:

exgcd,扩展欧几里得,扩欧,是求下面这个不定方程解的方法:

ax+by=gcd(a,b)

把后面的 gcd(a,b) 辗转相除一下再写成类似的形式(这里的 x,y 是对应 gcd(b,amodb)x,y,和上面的 x,y 没有关系):

bx+(amodb)y=gcd(b,amodb)

ax+by=gcd(a,b)=gcd(b,amodb)=bx+(aabb)y

ax+by=bx+(aabb)y

因为要求解 x,y,所以假设我们已经求解了 x,y,则要按 a,b 把两个方程分开,然后就可以递归求解了。(貌似没有为什么,就是这么处理然后是可以递归求解的)

ax+by=ay+b(xaby)

解出 x,y 就要求解 xy,注意求解 xy 的时候,他们对应的 a,b 实际上是原先 x,ya,bb,amodb

递归就能求出 ax+by=gcd(a,b) 一组特解了,最后当 b=0 的时候递归终止,此时 ax+by=gcd(a,b) 的解显然是 x=1,y=00 和非零数的 gcd 仍为那个数本身)。

扩展欧几里得算法得到的特解一定有 |x|a,|y|b

设解出的特解为 x0,y0,则通解为 x0+bdt,y0adtd=gcd(a,b)

Code

void exgcd(int a, int b, int &x, int &y) {
	if(!b) { x = 1, y = 0; return ; }
	exgcd(b, a % b, x, y);
	int nx = y, ny = x - (a / b) * y;
	x = nx, y = ny;
}

后记

这样最基础的 exgcd 就到这里了,如果想进一步理解更深层的 exgcd,推荐阅读:

洛谷日报#288 [_Leaving]同余方程-5天从入门到入土

本文参考文章

posted @   do_while_true  阅读(351)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?

This blog has running: 1845 days 1 hours 34 minutes 12 seconds

点击右上角即可分享
微信分享提示