O(n)递推求逆元
第一种:
适用于需要一定区域内的逆元的情况
代码:
void getinv(int n)
{
inv[1]=1; inv[0]=1;
for(int i=2;i<n;i++)
inv[i]=(1LL*(mod-mod/i)*inv[mod%i])%mod;
}
证明:
a*x+b=mod
a*x%mod=(-b)%mod
-a%mod=inv[x]*b%mod
inv[x]=(-a)*inv[b]%mod;
第二种:
适用于求组合数等需要阶乘的逆元的情况:
先求出阶乘,再求出n!的逆元,倒推出 i! 的逆元。
(n要小于mod否则fac为0)
代码:
void init()
{
fac[0]=1; inv[0]=1;
for(int i=1;i<=n;i++)
fac[i]=(1LL*fac[i-1]*i)%mod;
inv[n]=modpow(fac[n],mod-2);
for(int i=n-1;i>=1;i--)
inv[i]=(1LL*inv[i+1]*(i+1))%mod;
}
证明:
1/i!=1/(i+1)! * (i+1)