扩展欧几里得算法(ExGCD)
瞎扯
ExGCD用于求解不定方程
的一组特解。常用于求解同余方程,比如求模非质数意义下的逆元。
推导
主体
首先,不定方程有解的充分必要条件由裴蜀定理给出
于是,我们只需关注
的解。(原方程的解只需分别对,乘上即可求出)
(下文中%代指取模操作)
考虑递归的求解。假设我们已经知道了不定方程
的解,,即
现在尝试利用此式构造出原方程的解,。
由 以及
原式化为
拆开括号
我们的目标是构造出系数为,的原方程,故整理得
成功构造。故
该递归的边界条件同欧几里得算法,当时,方程为
,即该方程的一组特解。
构造最小的特解
Exgcd常用于逆元求解。这时需要找到一组解,使得最小(正整数范围内)。可以这样构造。
我们知道,不定方程的通解形式为
其中,
upd:友情提示一下大家通常了解到的通解形式里面的,但是实际上该通解形式仅在时正确(不过如果你没有意识到这一点也没啥问题,因为仍然能求出MOD内的逆元,,,)
所以,以为例,最小的正整数,然后将其带入不定方程解出即可。
Code
namespace ExGcd{ ll x,y; ll ExGcd(ll a,ll b){ ll ans; if(b==0){ x=1;y=0;ans=a; }else{ ans=ExGcd(b,a%b); ll x1=x,y1=y; x=y1;y=x1-a/b*y1; } return ans; } bool SolveEqu(ll a,ll b,ll c){ ll d=ExGcd(a,b); if(c%d!=0) return 0; x*=c/d;y*=c/d; //Minimize x ll t=b/d; x=(x%t+t)%t; y=(c-a*x)/b; return 1; } } //以下为求逆元 ll Inv(ll a,ll m){ ExGcd::SolveEqu(a,m,1); return ExGcd::x; }
板题:洛谷P1082 同余方程,随便改改上面的程序即可。
2019/12/21
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现