快速幂求逆元
ll quickpow(ll base,ll power) { ll ret=1; for(;power;power>>=1) { if(power&1) { ret=(ret*base)%mod; } base=(base*base)%mod; } return ret; }
食用方法:quickpow(base,mod-2)
正确性:费马小定理
扩展欧几里得求逆元
ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1,y=0; return a; } else { ll ans=exgcd(b,a%b,x,y); ll temp=x; x=y; y=temp-a/b*y; return ans; } }
(其实我是直接用的poj1061的代码的)
食用方法:a为所求数,x为逆元,b为模数,y为随便。
正确性:
我们设逆元为x
有ax=1(mod p)
ax+pk=1
求出求出x即可
首先 假如我们要求(a/b)mod p 我们只用求a*b^1 mod p即可
线性求所有逆元:
void inverse(int n) { inv[1]=1; for(int i=2;i<=n;i++) { inv[i]=((mod-(mod/i))*(inv[mod%i]))%mod; } }
食用方法:我不多说了
正确性:http://blog.miskcoo.com/2014/09/linear-find-all-invert
不过以上都不是重头 重头是这个:
http://blog.csdn.net/the301stdoub/article/details/47017773
假如我们知道了inv[n!],由于inv[(n-1)!]=inv[n!]*n 我们可以知道n-1的阶乘 因此我们可以线性求所有阶乘的逆元
void getfacinv(int n) { fac[0]=1; for(int i=1;i<=n;i++) { fac[i]=(fac[i-1]*i)%mod; } inv[n]=quickpow(fac[n],mod-2)%mod; for(int i=n-1;i>=1;i--) { inv[n]=(inv[n+1]*(n+1))%mod; } }
所以我想大家应该知道我想干啥了。