一、逆元是什么
当我们平常做题遇到需要求类似于(a/b)%p的时候,显然这个时候不能像做加法和减法一样展开成((a%p)/(b%p))%p。
这个时候就要用到逆元了。
假设c是b的逆元,那么就可以得到b*c1(mod p),那么上式就可以写成
(a/b)*1 %p=(a/b)*b*c%p=(a*c)%p
这样我们就把除法取模问题转化成乘法取模问题了。
二、求逆元
1、费马小定理
内容:如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)
那么上式就等于a*a^(p-2)≡1(mod p),即a得逆元就是a^(p-2).
再利用快速幂就可以求得。
复杂度 O(logn)
const int mod=1000000007;
const int N=1e5+10;
// 费马小定理
ll qsm(ll a,ll b)
{
if(b<0)
return 0;
ll ans=1;
a%=mod;
while(b){
if(b&1)
ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans;
}
ll inv1(ll a)
{
return qsm(a,mod-2);
}
2、逆元线性筛
这个可以求一系列的数的逆元,要求p为质数
复杂度O(n)
const int mod=1000000007;
const int N=1e5+10;
ll inv[N];
ll inv2()
{
inv[1]=1;
for(int i=2;i<10000;i++)
inv[i]=inv[mod%i]*(mod-mod/i)%mod;
}