逆元的意义及其求法
意义
通俗的讲,逆元就可以看作是一个数的倒数的形式,不过是在取模的意义下,所以对于同一个数,在不同的模数下,逆元也是不一样的
那么他的形式就可以写作:
a
x
≡
1
(
m
o
d
m
)
ax\equiv 1\pmod{m}
ax≡1(modm),
x
x
x就是
a
a
a在模
m
m
m意义下的逆元,但当且仅当
g
c
d
(
a
,
m
)
=
1
gcd(a,m)=1
gcd(a,m)=1时,在模
m
m
m意义下
a
a
a有逆元
那么逆元有什么用呢?
他的用处十分广泛,当我在遇到组合数时,常常会取模,但是分数形式是不能直接取模的
即
b
a
≠
b
m
o
d
m
a
m
o
d
m
(
m
o
d
m
)
\frac{b}{a}\ne\frac{b\mod m}{a\mod m}\pmod{m}
ab=amodmbmodm(modm),但是
b
a
≡
b
∗
a
−
1
(
m
o
d
m
)
\frac{b}{a}\equiv b*a^{-1}\pmod{m}
ab≡b∗a−1(modm)
求法
逆元的求法很多,需要根据具体情况来选择
费马小定理(模数为质数)
由费马小定理可得,当
g
c
d
(
a
,
p
)
=
1
gcd(a,p)=1
gcd(a,p)=1且
p
p
p为质数时,有
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p-1}\equiv1\pmod{p}
ap−1≡1(modp)
⇒
a
∗
a
p
−
2
≡
1
(
m
o
d
p
)
\Rightarrow a*a^{p-2}\equiv1\pmod{p}
⇒a∗ap−2≡1(modp)
⇒
a
p
−
2
\Rightarrow a^{p-2}
⇒ap−2就是
a
a
a在模
p
p
p意义下的逆元
快速幂即可解决
时间复杂度
O
(
l
o
g
p
)
O(log p)
O(logp)
扩欧(万能)
其实一看到
a
x
≡
1
(
m
o
d
m
)
ax\equiv1\pmod{m}
ax≡1(modm),就很容易想到扩欧
转换为
⇒
a
x
+
k
m
=
1
\Rightarrow ax+km=1
⇒ax+km=1
那么直接扩欧解决
这种方法,只要存在逆元就一定能求解
时间复杂度
O
(
l
o
g
n
)
O(logn)
O(logn)
递推求多个逆元
题目中往往要求我们求出多个逆元,且求单个逆元的时间复杂度为 O ( 1 ) O(1) O(1),显然以上两种方法很难解决,于是考虑递推求满足一些特殊性质(下文会提到)的多个逆元
线性求逆元
结论:
i
n
v
[
i
]
=
(
p
−
p
/
i
)
∗
i
n
v
[
p
m
o
d
i
]
m
o
d
p
inv[i]=(p-p/i)*inv[p\mod i]\mod p
inv[i]=(p−p/i)∗inv[pmodi]modp
推导过程:
令
p
=
i
∗
n
+
k
,
1
≤
n
<
p
,
0
≤
k
<
i
p=i*n+k,1\leq n<p,0\leq k<i
p=i∗n+k,1≤n<p,0≤k<i
⇒
n
=
p
/
i
,
k
=
p
m
o
d
i
\Rightarrow n=p/i,k=p\mod i
⇒n=p/i,k=pmodi
⇒
i
∗
n
+
k
≡
0
(
m
o
d
p
)
\Rightarrow i*n+k\equiv0\pmod{p}
⇒i∗n+k≡0(modp)
⇒
−
i
∗
n
≡
k
(
m
o
d
p
)
\Rightarrow -i*n\equiv k\pmod{p}
⇒−i∗n≡k(modp)
两边同乘
i
−
1
∗
k
−
1
i^{-1}*k^{-1}
i−1∗k−1
⇒
−
n
∗
i
n
v
[
k
]
≡
i
n
v
[
i
]
(
m
o
d
p
)
\Rightarrow -n*inv[k]\equiv inv[i]\pmod{p}
⇒−n∗inv[k]≡inv[i](modp)
⇒
i
n
v
[
i
]
≡
(
p
−
p
/
i
)
∗
i
n
v
[
p
m
o
d
i
]
(
m
o
d
p
)
\Rightarrow inv[i]\equiv (p-p/i)*inv[p\mod i]\pmod{p}
⇒inv[i]≡(p−p/i)∗inv[pmodi](modp)
⇒
i
n
v
[
i
]
=
(
p
−
p
/
i
)
∗
i
n
v
[
p
m
o
d
i
]
m
o
d
p
\Rightarrow inv[i]=(p-p/i)*inv[p\mod i]\mod{p}
⇒inv[i]=(p−p/i)∗inv[pmodi]modp
同时预处理
i
n
v
[
1
]
=
1
inv[1]=1
inv[1]=1,那么就可以线性求解逆元了
时间复杂度
O
(
n
)
O(n)
O(n)
线性求阶乘逆元
由于求解逆元其实就可以看作是求解倒数
那么由于
1
(
n
+
1
)
!
∗
(
n
+
1
)
=
1
n
!
\frac{1}{(n+1)!}*(n+1)=\frac{1}{n!}
(n+1)!1∗(n+1)=n!1
⇒
i
n
v
[
n
!
]
=
i
n
v
[
(
n
+
1
)
!
]
∗
(
n
+
1
)
m
o
d
p
\Rightarrow inv[n!]=inv[(n+1)!]*(n+1)\mod p
⇒inv[n!]=inv[(n+1)!]∗(n+1)modp