https://www.acwing.com/problem/content/878/
给定 n n n组 a i , p i a_i,p_i ai,pi,其中 p i p_i pi是质数,求同余方程 a i x ≡ 1 ( m o d p ) a_ix\equiv 1(\mod p) aix≡1(modp)的解。若无解则输出impossible。若有解则返回位于 1 ∼ p − 1 1\sim p-1 1∼p−1的解。
数据范围:
1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1≤n≤105
1 ≤ a i , p i ≤ 2 × 1 0 9 1\le a_i,p_i\le 2\times 10^9 1≤ai,pi≤2×109
其实是求 a a a模 p p p的逆元。如果 p ∣ a p|a p∣a,那么 ∀ x , p ∣ a x \forall x, p|ax ∀x,p∣ax,则无解;否则,由费马小定理, a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(\mod p) ap−1≡1(modp),所以有 a a p − 2 ≡ 1 ( m o d p ) aa^{p-2}\equiv 1(\mod p) aap−2≡1(modp),所以 a a a的逆元就是 a p − 2 a^{p-2} ap−2,那么其在 1 ∼ p − 1 1\sim p-1 1∼p−1中的逆元就是 a p − 2 m o d p a^{p-2}\mod p ap−2modp。而 a p − 2 m o d p a^{p-2}\mod p ap−2modp可以用快速幂来做。代码如下:
#include
using namespace std;
// 直接套用快速幂模板
int fast_pow(int a, int k, int p) {
long res = 1;
while (k) {
if (k & 1) res = res * a % p;
k >>= 1;
a = (long) a * a % p;
}
return (int) res;
}
int main() {
int n;
cin >> n;
while (n--) {
int a, p;
scanf("%d%d", &a, &p);
int res = fast_pow(a, p - 2, p);
if (a % p != 0) printf("%d\n", res);
else printf("impossible\n");
}
return 0;
}
每次询问时间复杂度 O ( log p i ) O(\log p_i) O(logpi),空间 O ( 1 ) O(1) O(1)。