快速幂求逆元
我们首先看一下乘法逆元的定义,若整数
b
,
m
b,m
b,m 互质,并且对于任意的整数
a
a
a,如果满足
b
∣
a
b|a
b∣a,则存在一个整数
x
x
x,使得
a
b
\frac {a}{b}
ba≡
a
×
x
(
m
o
d
m
)
a×x(mod\ m)
a×x(mod m),则称
x
x
x 为
b
b
b 的模
m
m
m 乘法逆元,记为
b
−
1
(
m
o
d
m
)
b^{−1}(mod\ m)
b−1(mod m)。
b
b
b 存在乘法逆元的充要条件是
b
b
b 与模数
m
m
m 互质。当模数
m
m
m 为质数时,
b
m
−
2
b^{m−2}
bm−2 即为
b
b
b 的乘法逆元(这是可以证明的)。一定要注意逆元有可能是不存在的,当
b
b
b与
m
m
m不互质时,逆元就是不存在的。我们求得就是在
m
m
m为质数的情况下的逆元,这样问题就转换为了求
b
m
−
2
m
o
d
m
b^{m-2}\ mod\ m
bm−2 mod m,这时的做法就和快速幂一模一样了,参考
快速幂算法
接下来看一下快速幂求逆元的代码:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
int n;
int qmi(int a, int k, int p)
{
int res = 1;
while(k)
{
if(k & 1) res = (LL)res * a % p;
k >>= 1;
a = (LL)a * a % p;
}
return res;
}
int main()
{
scanf("%d", &n);
while(n --)
{
int a, p;
scanf("%d%d", &a, &p);
int res = qmi(a, p - 2, p);
if(a % p) printf("%d\n", res);//这里为什么不用a与p互质这个条件,而选择相对弱一点的a是否为p的倍数呢,因为这道题中已经限制了p为质数
else printf("impossible\n");
}
return 0;
}