乘法逆元
什么是乘法逆元
我们知道取模是有可加、可减、可乘性的但是唯独没有可除性。
这就意味着当我们想要知道
a
b
%
c
=
?
\frac{a}{b} \% c = ?
ba%c=? 的时候只能老老实实地先算出
a
b
\frac{a}{b}
ba。小的数还好,如果是这个呢?
C
m
n
%
M
o
d
=
n
!
m
!
×
(
n
−
m
)
!
%
M
o
d
=
?
C_{m}^{n} \% Mod = \frac{n!}{m!\times (n - m)!} \% Mod = ?
Cmn%Mod=m!×(n−m)!n!%Mod=?
这不就废了吗?
因此,为了解决这个问题,我们的逆元就闪亮登场了。
逆元的定义
如果 i n v × b ≡ 1 ( m o d c ) inv \times b \equiv 1 \pmod{c} inv×b≡1(modc) 那么我们就称 i n v inv inv 是 b b b 在对 c c c 取模意义下的逆元。
那么逆元是如何解决上述问题的呢?
因为,除以一个数再取模 = 乘上一个数的逆元再取模 这意味着我们可以边算边取模了。
证明:
设
a
/
b
=
k
×
c
+
r
a/b = k \times c + r
a/b=k×c+r
两边同时乘以
b
b
b 得:
a
=
k
×
c
×
b
+
r
×
b
a = k \times c \times b + r \times b
a=k×c×b+r×b
再乘上
i
n
v
inv
inv 得:
a
×
i
n
v
=
k
×
c
×
b
×
i
n
v
+
r
×
b
×
i
n
v
a \times inv = k \times c \times b \times inv + r \times b \times inv
a×inv=k×c×b×inv+r×b×inv
我们知道
i
n
v
×
b
≡
1
(
m
o
d
c
)
inv \times b \equiv 1 \pmod{c}
inv×b≡1(modc)
所以
a
×
i
n
v
≡
k
×
c
×
b
×
i
n
v
+
r
×
b
×
i
n
v
≡
k
×
c
+
r
(
m
o
d
c
)
a \times inv \equiv k \times c \times b \times inv + r \times b \times inv \equiv k \times c + r \pmod{c}
a×inv≡k×c×b×inv+r×b×inv≡k×c+r(modc)
得证
逆元的求法
既然逆元这么好用,那么我们如何算出一个数的逆元呢?
通用方法
其实逆元的本质就是求解二元一次方程:
i
n
v
×
b
=
k
×
c
+
1
inv \times b = k \times c + 1
inv×b=k×c+1
因为
k
k
k 可以为负,所以我们不妨吧这个式子转换为
i
n
v
×
b
+
k
×
c
=
1
inv \times b + k \times c = 1
inv×b+k×c=1
这样就是一个标准的二元一次方程了。
根据裴蜀定理, 这个方程当且仅当
g
c
d
(
b
,
c
)
=
1
gcd(b, c) = 1
gcd(b,c)=1 的时候有解。
然后就是 扩展欧几里得 的板子了,求出来以后我们一般习惯让逆元是正数。
模数质数的时候
但是上述的方法仍然有些麻烦。有么有别的方法呢?
当模数为质数的时候我们可以利用费马小定理 (欧拉定理的特殊情况)求解, 其实就是
a
ϕ
(
m
o
d
)
≡
1
(
m
o
d
m
o
d
)
a^{\phi(mod)} \equiv 1 \pmod{mod}
aϕ(mod)≡1(modmod)
然后因为
m
o
d
mod
mod 为质数,所以
ϕ
(
m
o
d
)
=
m
o
d
−
1
\phi(mod) = mod - 1
ϕ(mod)=mod−1
a
m
o
d
−
1
≡
1
(
m
o
d
m
o
d
)
a
×
a
m
o
d
−
2
≡
1
(
m
o
d
m
o
d
)
a^{mod - 1} \equiv 1 \pmod{mod} \\ a \times a^{mod - 2} \equiv 1 \pmod{mod}
amod−1≡1(modmod)a×amod−2≡1(modmod)
因此我们发现
a
m
o
d
−
2
a^{mod-2}
amod−2 就是
a
a
a 的逆元。
线性递推
有的时候我们要求出从
1
1
1 开始的所有数的逆元,一个一个求显然太慢,我们可以递推
inv[i] = (Mod - Mod / i) * inv[Mod % i] % Mod