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

被折叠的 条评论
为什么被折叠?



