模板汇总——逆元
轉(zhuǎn)自倉鼠大神的博客
1.快速冪求法
費(fèi)馬小定理(a和p互質(zhì))
a^(p-1) ≡1 (mod p)
a^(p-2) ≡ inv(a) (mod p)
1 LL pow_mod(LL a, LL b, LL p){//a的b次方求余p 2 LL ret = 1; 3 while(b){ 4 if(b & 1) ret = (ret * a) % p; 5 a = (a * a) % p; 6 b >>= 1; 7 } 8 return ret; 9 } 10 LL Fermat(LL a, LL p){//費(fèi)馬求a關(guān)于b的逆元 11 return pow_mod(a, p-2, p); 12 } View Code?
?
2.擴(kuò)展歐幾里德算法
1 #include<cstdio> 2 #define LL long long 3 void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){ 4 if (!b) {d = a, x = 1, y = 0;} 5 else{ 6 ex_gcd(b, a % b, y, x, d); 7 y -= x * (a / b); 8 } 9 } 10 LL inv(LL t, LL p){//如果不存在,返回-1 11 LL d, x, y; 12 ex_gcd(t, p, x, y, d); 13 return d == 1 ? (x % p + p) % p : -1; 14 } 15 int main(){ 16 LL a, p; 17 while(~scanf("%lld%lld", &a, &p)){ 18 printf("%lld\n", inv(a, p)); 19 } 20 } View Code?
?
3.遞推法
在O(n)的復(fù)雜度內(nèi)算出n個(gè)數(shù)的逆元(p需要為質(zhì)數(shù))
1 #include<cstdio> 2 const int N = 200000 + 5; 3 const int MOD = (int)1e9 + 7; 4 int inv[N]; 5 int init(){ 6 inv[1] = 1; 7 for(int i = 2; i < N; i ++){ 8 inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD; 9 } 10 } 11 int main(){ 12 init(); 13 } View Code?
4.組合數(shù)逆元?
1 int F[N], Finv[N], inv[N];/// F是階層 Finv是逆元的階層 2 void init(){ 3 inv[1] = 1; 4 for(int i = 2; i < N; i++) 5 inv[i] = (mod - mod/i) * 1ll * inv[mod % i] % mod; 6 F[0] = Finv[0] = 1; 7 for(int i = 1; i < N; i++){ 8 F[i] = F[i-1] * 1ll * i % mod; 9 Finv[i] = Finv[i-1] * 1ll * inv[i] % mod; 10 } 11 } 12 int comb(int n, int m){ /// C(n,m) 13 if(m < 0 || m > n) return 0; 14 return F[n] * 1ll * Finv[n-m] % mod * Finv[m] % mod; 15 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/MingSD/p/8414503.html
總結(jié)
- 上一篇: 2018.5.28 PSOC第一枪:基于
- 下一篇: 微信小程序开发总结