欧几里得算法与 EX
1.【算法学习】排序2.【算法学习】Manacher 马拉车3.【算法学习】KMP 算法4.LCA 最近公共祖先(树链和倍增)这次真有树链了!!!5.线段覆盖问题6.【算法学习】学换根dp有感7.二分图最大匹配8.【算法学习】01BFS9.洛谷 P1892 [BOI2003] 团伙 种类并查集 扩展域并查集10.【算法学习】高斯消元法11.贝叶斯公式12.背包13.【算法学习】模拟退火14.【算法学习】基环树15.【算法学习】树链部分16.【算法学习】莫队17.【算法学习】分块九讲18.平衡树19.圆方树20.【算法学习】点分治21.公式22.【算法学习】笛卡尔树23.【算法学习】悬线法
24.欧几里得算法与 EX
25.【算法学习】逆元与求解26.【算法学习】费马定理27.三分28.裴蜀定理29.【算法学习】欧拉函数φ30.【算法学习】二维转一维问题31.【算法学习】扫描线32.【算法学习】矩阵乘法33.【算法学习】同余最短路34.【算法学习】组合数学35.【算法学习】反悔贪心欧几里得算法
欧几里得算法又称辗转相除法,用来求两个数的最大公约数的算法。
省流:\(gcd(a,b)=gcd(b,a\mod b)\)
点击查看代码
#include <bits/stdc++.h> using namespace std; int a,b; int gcd(int x,int y){ return y==0?x:gcd(y,x%y); } int main(){ cin>>a>>b; cout<<gcd(a,b); return 0; }
拓展欧几里得算法 exgcd
常用于求解 \(ax+by=gcd(a,b)\) 的一组可行解。
接下来就是推例子了:
\[\because gcd(a,b)=gcd(b,a\mod b)
\]
\[\therefore ax+by=bx_2+(a \mod b)y_2
\]
\[\because a \mod b=a-b\times \lfloor \frac{a}{b} \rfloor
\]
\[\therefore ax+by=bx_2+( a-b\times \lfloor \frac{a}{b} \rfloor )y_2
\]
\[\therefore ax+by=bx_2+ay_2-by_2\lfloor \frac{a}{b} \rfloor
\]
\[\therefore ax+by=ay_2+b(x_2-y_2\lfloor \frac{a}{b} \rfloor)
\]
然后我们就发现 \(x=y_2,y=x_2-y_2\lfloor \frac{a}{b} \rfloor\)
\(x_2,y_2\) 又可以从 \(x_3,y_3\) 推过来。
我们就需要不断做欧几里得法,当 \(a=gcd(a,b),b=0\) 时,我们这时取 \(x_n=1,y_n=0\),因为 \(b=0\) 所以 \(y_n\) 取任何数都没问题,但取 \(0\) 的时候 \(x\) 和 \(y\) 增长速度更慢一些,还有注意解可能为负数的情况,所以要取模变正数。
点击查看代码
#include <bits/stdc++.h> using namespace std; #define ll long long void exgcd(ll a,ll b,ll &x,ll &y){ if(b==0){ x=1,y=0; return; } exgcd(b,a%b,y,x); y-=a/b*x; } int main(){ ios::sync_with_stdio(false); ll a,b; cin>>a>>b; ll d=__gcd(a,b); if(b%d!=0){ cout<<"impossible\n"; } else{ ll x,y; exgcd(a,b,x,y); x=(x*(b/d)%b+b)%b;//注意这要调整解 cout<<x<<"\n"; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)