[模板]逆元
1.费马小定理|欧拉定理
由费马小定理得当p为质数,(a,p)=1时,ap-1≡1 mod p
所以ap-2≡a-1
由欧拉定理当(a,p)=1但p可以不为质数,aΦ(p)≡1 mod p
2.扩展欧几里德
设a的逆元为x,则可以视作ax≡1 mod p
可以视作 ax-bp=1
然后用扩展欧几里德就行了。
核心代码:
int exgcd(int &x,int &y,int a,int b) { if(!b) {x=1,y=0;return a;} int g=exgcd(x,y,b,a%b),t=y; y=x-y*(a/b); x=t; return g; } exgcd(x,y,i,p); printf("%d\n",(x+p)%p);
3.递推
设 t=p/i,k=p mod i
ti+k≡0 mod p
ti≡-k mod p
t×k-1≡-i-1 mod p
i-1=-t×k-1
因为k一定小于i,所以k的逆元已经知道,t是已知量。
所以可以O(n)的递推出n以下的所有逆元。
核心代码:
inv[1]=1; for(int i=2;i<=n;i++){ inv[i]=(p-(p/i))*inv[p%i]%p; }
4.阶乘逆元
阶乘逆元可以O(n)递推。
设inv[i]表示 i! 的逆元。
i!×(i+1)×inv[i+1]≡1 mod p
inv[i]≡(i+1)×inv[i+1] mod p
在求大组合数时常用。
inv[n]=ksm(fac[n],mod-2); for(int i=n-1; i; i--) inv[i]=inv[i+1]*(i+1)%mod;
我是咸鱼。转载博客请征得博主同意Orz