开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情
题意:求关于x的同余方程 ax≡1(modb) 的最小正整数解。
思路:先看一下扩展欧几里得算法,常用于求ax+by=gcd(a,b)的一组可行解。
过程:设
有欧几里得定理可知:
所以
又因为
所以
因为,所以
将x2,y2不断带入递归求解直至gcd为0递归x=1,y=0回去求解
假如我们要将x扩大,即变成x+p,我们需要将y缩小,需要变成y-q.
联立解得,我们需要获得尽可能小的正整数p,q.那么就有,即最小值为,得出,如果x偏大就需要求一个k使得,接着我么们就可以,最后x就是最小的正整数
【题解】【P5656-【模板】二元一次不定方程(exgcd)】 - 古明地觉世界第一! - 洛谷博客 (luogu.com.cn)
#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e18;
const double pi=acos(-1);
const int N=1e6+100;
ll qpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int temp=y;
y=x-(a/b)*y;
x=temp;
return r;
}
signed main()
{
//ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int a,b,c=1;
cin>>a>>b;
int g=__gcd(a,b);
int x,y,p=b/g,q=a/g,k;
exgcd(a,b,x,y);
x*=c/g;y*=c/g;
if(x<0) k=ceil((1.0-x)/p),x+=p*k,y-=q*k;
else if(x>=0) k=(x-1)/p,x-=p*k,y+=q*k;
cout<<x<<endl;
return 0;
}