【知识点】求逆元
比赛中通常使用(费马小定理/欧拉定理)
ll qkpow(ll a,ll p,ll mod)//快速幂 { ll t=1,tt=a%mod; while(p) { if(p&1)t=t*tt%mod; tt=tt*tt%mod; p>>=1; } return t; } ll getInv(ll a,ll mod) { return qkpow(a,mod-2,mod);//a的mod-2次方 }
性能分析:
- O(logmod)
- 适用范围:一般在mod是个素数的时候用,比扩欧快一点而且好写。
扩展欧几里得算法:
ll exgcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得算法 { if(b==0) { x=1,y=0; return a; } ll ret=exgcd(b,a%b,y,x); y-=a/b*x; return ret; } ll getInv(int a,int mod)//求a在mod下的逆元,不存在逆元返回-1 { ll x,y; ll d=exgcd(a,mod,x,y); return d==1?(x%mod+mod)%mod:-1; }
- 时间复杂度:O(logn)(实际是斐波那契数列)
- 适用范围:只要存在逆元即可求,适用于个数不多但是mod很大的时候,也是最常见的一种求逆元的方法。