定义
- 当 a x ≡ 1 ( m o d b ) ax\equiv 1 \pmod{b} ax≡1(modb) 时, x x x 即为 a a a 在膜 b b b 意义下的逆元。
- 逆元的数学符号是 i n v inv inv , a a a 在膜 b b b 意义下的逆元记作 i n v ( a , b ) inv(a,b) inv(a,b) 。注意不要写反了。
求法
-
费马小定理
这是一个在数论中很重要的定理:在 p p p 为质数且 gcd ( a , p ) = 1 \text{gcd}(a,p)=1 gcd(a,p)=1 时, 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 ) a×a^{p-2}\equiv 1 \pmod{p} a×ap−2≡1(modp)
所以 a p − 2 a^{p-2} ap−2 就是 a a a 在膜 p p p 意义下的逆元。
用快速幂求出 a p − 2 mod p a^{p-2}\text{ mod }p ap−2 mod p 就是答案。
可以用 O ( log p ) \mathcal{O(\log p)} O(logp) 的速度求逆元,但是有特殊限制。 -
扩展欧几里得算法
本人博客里的扩欧详解已经讲了用扩欧求逆元的方法,所以这里就不讲了,直接附链接:扩欧详解
速度也是 log \log log 级别的(但是具体是哪个数的 log \log log 我不知道),而且没有特殊限制。 -
线性求 1 ∼ n 1\sim n 1∼n 的逆元
内容较多,所以写到这里了
可以 O ( n ) \mathcal{O(n)} O(n) 求出 1 ∼ n 1\sim n 1∼n 的逆元 -
线性求 1 ∼ n 1 \sim n 1∼n 阶乘的逆元
设模数为 p p p 。
首先求出 n ! n! n! 的逆元,然后我们可以得到 i n v ( ( n − 1 ) ! , p ) = i n v ( n ! , p ) × n   m o d   p inv((n-1)!,p)=inv(n!,p)\times n \bmod p inv((n−1)!,p)=inv(n!,p)×nmodp 。像这样逆推就可以了。
求 i n v ( n ! , p ) inv(n!,p) inv(n!,p) 的复杂度仅为 log \log log 级别,忽略不计的话这就是 O ( n ) \mathcal O(n) O(n) 的了
你也可以用线性求阶乘+线性求逆元来完成线性求阶乘逆元,但这种方法常数较大,码量也略大一点点,不建议使用