通俗的讲,逆元就可以看作是一个数的倒数的形式,不过是在取模的意义下,所以对于同一个数,在不同的模数下,逆元也是不一样的
那么他的形式就可以写作: 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 ≤ n < p , 0 ≤ k < i p=i*n+k,1\leq n
⇒ 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