[模板]逆元

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);
exgcd

 

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;
阶乘逆元

 

posted @ 2018-10-16 11:57  SWHsz  阅读(186)  评论(0编辑  收藏  举报