扩展欧几里得(新)
重新整理一下扩欧。
扩展欧几里得就是欧几里得算法也就是辗转相除法的扩展应用,扩展后的作用主要为求二元一次方程组的一个解。
基本原理
众所周知,一个式子是无法确定两个未知数的唯一值的,因此 exgcd 只能解出一种符合要求的解,但是因为有通解的存在,你可以由这个解推出其他所有的可能解。
先看看扩展的地方,欧几里得的原理是
该怎么回代呢,这里比较抽象,我们想一想,辗转完一次后的
int gcd(int a, int b) { return b ? a : gcd(b, a % b); }
可以发现我们向下传的
整理可得
而我们之前的式子有
这就产生对应关系了,如果我们知道一种
还记得上面说的,我们可以求出最后一个
代码实现
然后就是代码中的实现方式,为了把后面的
我们可以写出如下代码
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 tx = x, ty = y; // 即x',y' y = tx - a / b * ty; x = ty; return d; }
但实际上代码还可以精简,因为是用传址带回来的
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 = y; y = x - a / b * t; x = t; return d; }
但这还不是我们最常用的,众所周知,辗转相除法在代码实现上为了让 gcd(b, a % b)
,而不是 gcd(a % b, b)
。这里我们可以借鉴思想,把扩展欧几里得里面的
在求出当前
你会发现,
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, y, x); y -= a / b * x; return d; }
而这就是我们最常用的扩展欧几里得代码。
至此,本文结束。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】