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
解题思路
找到K使得K*M%N=1
也就是找到K使得K*M=x*N+1
也就是找到K使得K*M+(-N)*x=1
恰巧扩展欧几里得算法解决的问题就是
已知a,b,求出满足式子
a ∗ x + b ∗ y = g c d ( a , b ) a*x+b*y=gcd(a,b) a∗x+b∗y=gcd(a,b)
的x,y,gcd(a,b)值
式子两边同时除以gcd(a,b),
如果X/gcd(a,b)是整数,
那就是结果K,如果不是正数,可以把y个b分给a*x
也就是
a ∗ ( x + b ) + b ∗ ( y − a ) = g c d ( a , b ) a*(x+b)+b*(y-a)=gcd(a,b) a∗(x+b)+b∗(y−a)=gcd(a,b)
再进行两边同时除法操作,直至找到整数结果
x可能是负数,所以也要判断排除
AC代码
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll m, n, k;
ll extend_Euclid(ll a, ll b, ll &x, ll &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
ll q = extend_Euclid(b, a%b, y, x);
y = y- (a / b)*x;
return q;
}
int main()
{
int i, j, k;
ll x, y;
cin >> m >> n;
ll t = extend_Euclid(m, n, x, y);
ll temp = x / t;
while (temp*t!=x||temp<=0)
{
x += n;
temp = x / t;
}
cout << temp << endl;
return 0;
}