快速幂求逆元 费马小定理
董晓算法:G13 同余式 乘法逆元 费马小定理(通俗易懂)
[AcWing876] 快速幂求逆元
题目描述
给定 \(n\) 组 \(a_i, p_i\),其中 \(p_i\) 是质数,求 \(a_i\) 模 \(p_i\) 的乘法逆元,若逆元不存在则输出 impossible
。
注意:请返回在 \(0 \sim p-1\) 之间的逆元。
乘法逆元的定义
若整数 \(b,m\) 互质,并且对于任意的整数 \(a\),如果满足 \(b|a\),则存在一个整数 \(x\),使得 \(\frac{a}{b} ≡a \times x \pmod m\),则称 \(x\) 为 \(b\) 的模 \(m\) 乘法逆元,记为 \(b^{-1} \pmod m\)。
\(b\) 存在乘法逆元的充要条件是 \(b\) 与模数 \(m\) 互质。当模数 \(m\) 为质数时,\(b^{m-2}\) 即为 \(b\) 的乘法逆元。
输入格式
第一行包含整数 \(n\)。
接下来 \(n\) 行,每行包含一个数组 \(a_i, p_i\),数据保证 \(p_i\) 是质数。
输出格式
输出共 \(n\) 行,每组数据输出一个结果,每个结果占一行。
若 \(a_i\) 模 \(p_i\) 的乘法逆元存在,则输出一个整数,表示逆元,否则输出 impossible
。
数据范围
\(1 \le n \le 10^5\),
\(1 \le a_i,p_i \le 2\times 10^9\)
输入样例:
3
4 3
8 5
6 3
输出样例:
1
2
impossible
算法
费马小定理
设 \(n\) 是质数,\(a\) 是正整数且与 \(n\) 互质,有 \(a^{n-1}\equiv 1\ (mod \ n)\)。
则 \(a ^{n-2}\ mod \ n\\\) 就是 \(a\) 模 \(n\) 的逆。
C++ 代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll fastPow(int a, int b, int p)
{
auto res = 1ll;
while (b){
if (b & 1) res = res * 1ll * a % p;
a = a * 1ll * a % p;
b >>= 1;
}
return res;
}
int main()
{
int n; cin >> n;
while (n--){
int a, p; cin >> a >> p;
if (a % p) cout << fastPow(a, p - 2, p) << endl;
else cout << "impossible" << endl;
}
return 0;
}