a和p互质,a才有关于p的逆元



1 //费马小定理(mod一定为质数)
2 ll poww(ll a,ll b,ll mod){
3 ll ans=1;
4 a%=mod;
5 while(b)
6 {
7 if(b&1) ans=(ans*a)%mod;
8 b>>=1;
9 a=(a*a)%mod;
10 }
11 return ans%mod;
12 }
13 ll inv(ll a,ll mod)
14 {
15 return poww(a,mod-2,mod);
16 }
17 //扩展欧几里得
18


typedef long long LL;

void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){

if (!b) {d = a, x = 1, y = 0;}

else{

ex_gcd(b, a % b, y, x, d);

y -= x * (a / b);

}

}

LL inv(LL t, LL p){//如果不存在,返回-1

LL d, x, y;

ex_gcd(t, p, x, y, d);

return d == 1 ? (x % p + p) % p : -1;

}



 

 



这个方法不限于求单个逆元,比前两个好,它可以在O(n)的复杂度内算出n个数的逆元

递归就是上面的写法,加一个记忆性递归,就可以了

递推这么写



#include<cstdio>
const int N = 200000 + 5;
const int MOD = (int)1e9 + 7;
int inv[N];
int init(){
inv[1] = 1;
for(int i = 2; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
}
int main(){
init();
}