题目描述
Given a positive integer y and a prime p, you are asked to find an integer x such that (x×y) mod p=1. If such x exists, output any x mod p. Otherwise, output -1.
Hint: For any integer a and positive integer b, a mod b is the remainder of a dividing b. Remind that a mod b is non-negative!
输入描述:
The first line of input contains a positive integer T, which is the number of test cases. (1≤T≤200,000)
For each test case, there will be one line containing 2 positive integers y, p. (1≤y,p≤109), p is guaranteed to be a prime
输出描述:
Output one integer for each test case. If such x exists, output any x mod p. Otherwise, output -1.
输入
3
1 97
2 97
3 97
输出
1
49
65
求逆元有两种方法,第一种是费马小定理,需要判断y与p是否互质。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 1;
int pow_fast(int a, int n, int mod) {
int res = 1;
while(n) {
if (n & 1) res = 1ll * res * a % mod;
n >>= 1;
a = 1ll * a * a % mod;
}
return res;
}
int main() {
int T;
cin >> T;
while(T --) {
int y, p;
cin >> y >> p;
// 需要判断 y 与 p 是否互质
if (y % p == 0) cout << -1 << endl;
else cout << pow_fast(y, p-2, p) << endl;
}
return 0;
}
第二种方法是扩展欧几里得算法,需要判断是负有解(ax + by = gcd (a, b))
#include<bits/stdc++.h>
using namespace std;
void extend_gcd(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1, y = 0;
return ;
}
extend_gcd(b, a % b, x, y);
int temp = x;
x = y;
y = temp - (a / b) * y;
}
int mod_inverse(int a, int m) {
int x, y;
extend_gcd(a, m, x, y);
return (x % m + m) % m;
}
int main() {
int T;
cin >> T;
while(T --) {
int y, p;
cin >> y >> p;
// 判断 ax + by = gcd(a, b) 是否有解
if (__gcd(y, p) == 1) cout << mod_inverse(y, p) << endl;
else cout << -1 << endl;
}
}