模数为0则逆元不存在。
x的模m逆存在且唯一的充要条件为x与m互质(gcd(x, m) = 1)
除法逆元有两种计算方法。
费马小定理(模数一定为质数):(a / b) % p = a * b^(p – 2) % p;
如果模数不为质数,但gcd(a, m) == 1,请使用欧拉定理
a
ϕ
(
m
)
≡
1
(
m
o
d
m
)
a^{\phi(m)} ≡ 1 (mod\ m)
aϕ(m)≡1(mod m)
如果模数不为质数,且gcd(a, m) != 1,请使用扩展欧拉定理
扩展欧几里得(不限制模数):
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1256
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x, y;
void extgcd(ll a, ll b, ll &x, ll &y)
{
if (b == 0) x = 1, y = 0;
else{
extgcd(b, a % b, y, x);
y -= (a / b) * x;
}
}
int main()
{
ll n, m;
cin >> n >> m;
extgcd(n, m, x, y);
if (x < 0) x += m;
cout << x << endl;
return 0;
}
线性求[1, n]的逆元:
inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = (ll)(p - p / i) * inv[p % i] % p;
线性求n个数的逆元(套装:预处理阶乘逆元):
void init()
{
fac[0] = inv[0] = s[0] = 1;
for (int i = 1; i < maxn; ++i) fac[i] = (ll)i * fac[i - 1] % mod;
for (int i = 1; i < maxn; ++i)
s[i] = (ll)s[i - 1] * fac[i] % mod;
sv[maxn - 1] = quickpow(s[maxn - 1], mod - 2);
for (int i = maxn - 1; i >= 1; --i)
sv[i - 1] = (ll)sv[i] * fac[i] % mod;
for (int i = 1; i < maxn; ++i)
inv[i] = (ll)sv[i] * s[i - 1] % mod;
}