欧几里得算法与 EX

欧几里得算法

欧几里得算法又称辗转相除法,用来求两个数的最大公约数的算法。

省流:\(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;
}
posted @   sad_lin  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示