简单理解
求逆元首先要有两个数,a、p,求解a % p的乘法逆元,设a % p = b,那么就是求b的乘法逆元。
首先要说的是,当a % p == 0的时候,就没有乘法逆元了。
假设b的乘法逆元是b^-1
求出的乘法逆元有个主要的性质就是
b
∗
b
−
1
%
p
=
1
b * b^{-1} \% p = 1
b∗b−1%p=1
在算法中,如果结果需要模上一个数,在计算的过程中,除以一个数都要变成乘上这个数的逆元,因为计算过程中除法不能和乘法,模运算等其他运算混着算,不然会错。主要就是这个功能,算是一个工具,求组合数的时候可能会用到。
求逆元
给定b、m,其中m为质数,求b模m的乘法逆元
对于任意整数 a, 满足b|a(b整除a),设存在整数一个x,满足
a
/
b
≡
a
∗
x
(
m
o
d
m
)
a/b\equiv a*x(mod\ \ m)
a/b≡a∗x(mod m)
可以推导得
1
/
b
≡
x
(
m
o
d
m
)
1/b\equiv x (mod\ \ m)
1/b≡x(mod m)
x即为b模m的乘法逆元
1
≡
b
∗
b
−
1
(
m
o
d
m
)
1 \equiv b * b^{-1} (mod\ \ m)
1≡b∗b−1(mod m)
由费马小定理可知
1
≡
b
(
m
−
1
)
(
m
o
d
m
)
1 \equiv b^{(m-1)} (mod\ \ m)
1≡b(m−1)(mod m)
带入可得
b
∗
b
−
1
≡
b
(
m
−
1
)
(
m
o
d
m
)
b * b^{-1} \equiv b^{(m - 1)} (mod\ \ m)
b∗b−1≡b(m−1)(mod m)
最终可得
b
−
1
≡
b
(
m
−
2
)
(
m
o
d
m
)
b^{-1} \equiv b^{(m - 2)} (mod\ \ m)
b−1≡b(m−2)(mod m)
证明可得
对于a,p两个正整数,其中p为质数。
若a % p == 0
则逆元不存在
当逆元存在时
a模p
在0 ~ p - 1
的乘法逆元是
a
p
−
2
a^{p - 2}
ap−2
Code
C++
#include <iostream>
using namespace std;
typedef long long ll;
ll ksm(ll a, ll b, int mod)
{
ll res = 1;
while (b)
{
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int main()
{
int n;
cin >> n;
while (n--)
{
ll a, p;
cin >> a >> p;
if (a % p == 0)
{
cout << "impossible" << endl;
}
else
{
cout << ksm(a, p - 2, p) << endl;
}
}
return 0;
}
Java
import java.util.*;
public class Main
{
static long ksm(long a, long b, long p)
{
long res = 1;
while(b != 0)
{
if (b % 2 == 1)
{
res = res * a % p;
}
a = a * a % p;
b /= 2;
}
return res;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for (int i = 1; i <= n; i++)
{
int a = in.nextInt();
int p = in.nextInt();
if (a % p == 0)
{
System.out.println("impossible");
}
else
{
System.out.println(ksm(a, p - 2, p));
}
}
in.close();
}
}