51nod 1256 乘法逆元
给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。
Input
输入2个数M, N中间用空格分隔(1 <= M < N <= 10^9)
Output
输出一个数K,满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。
Input示例
2 3
Output示例
2
乘法逆元求法:点击打开链接
此题只能用扩展欧几里得处理,其他简洁的写法都会RE(不知道哪里爆数据了,或者是除0了orz)
#include <iostream>
using namespace std;
/*
求逆元的间接写法
只能求a<m的情况,且a与m互质
求ax=1(mod m)的x的值,即逆元(0<a<m)
*/
/*
typedef long long ll;
ll inv(ll a,ll m)
{
if(a==1)
return 1;
return inv(m%a,m)*(m-m/a)%m;
}
int main()
{
ll n,m;
cin>>m>>n;
cout<<inv(m,n)<<endl;
return 0;
}
*/
/*
扩展欧几里得法(求ax+by=gcd)
返回d=gcd(a,b);和对应等式ax+by=d中的x、y
*/
typedef long long ll;
ll extendGcd(ll a,ll b,ll &x,ll &y)
{
if(a==0&&b==0)
{
return -1;
}
if(b==0)
{
x=1;
y=0;
return a;
}
ll d=extendGcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
//求逆元ax=1(mod n)
ll modReverse(ll a,ll n)
{
ll x,y;
ll d=extendGcd(a,n,x,y);
if(d==1)
return (x%n+n)%n;
else
return -1;//表示无逆元
}
int main()
{
ll n,m;
cin>>m>>n;
cout<<modReverse(m,n)<<endl;
return 0;
}