①欧几里得算法就是求gcd的有趣的辗转相除法,不再赘述啦0v0代码:
int gcd(int a,int b)
{
if(b==0)
return a;
else return gcd(b,a%b);
}
②扩展欧几里得算法需要解决这样的问题:两个非0整数a,b,求一组整数解(x,y),使得ax+by=gcd(a,b).(PS:证明之后补上0....0)
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int g=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return g;
}
③求逆元可以解决这样的问题:设a和m是整数,求a模m的逆元(逆元:设abm都是整数,m>1,有ab模m和1模m相等,它们拥有相同的余数,那么ab互为模m的逆元。也就是说,有两个数的乘积,如果模m后等于1,则它们互为m的逆元)。gcd(a,m)=1有解。即求ax+my=1=gcd(a,m)。代码:
ll inverse(ll a,ll m,ll c)
{
ll x,y;
ll g=exgcd(a,m,x,y);
if(c%g!=0)
return -1;
x*=c/g;
m/=g;
if(m<0)
m=-m;
ll ans=x%m;
if(ans<=0)
ans+=m;
return ans;
}
接下来给几个例子0V0↓例子1:zoj 3609,传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4712题意:输入一个n,给n组a和m,求每组a模m的最小逆元。吐槽:m=1的情况……窒息了代码:
//zoj 3609求最小逆元
#include
#include
#include
#include
#include
#include
#include