逆元板子集

Posted mrclr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆元板子集相关的知识,希望对你有一定的参考价值。

其实就是怕忘了……这里发一下线性求逆元以及阶乘的逆元的板子。

 

线性求逆元

逆元是啥我就不说了,但是线性递推式怎么来的我还是可以证明一下的。

 

求 i 的逆元,假设[1, i - 1]的逆元已知。

设 p = k * i + b,则 b = p % i, k = ?p / i? 。

则k * i + b Ξ 0 (mod p),所以b Ξ - k * i。

两边同乘inv[b]得:inv[b] * b Ξ - k * i * inv[b] (mod p)

化简得:    - k * i * inv[b] Ξ 1 (mod p)

两边同乘inv[i]得:inv[i] Ξ - k *inv[b] (mod p)

        inv[i] Ξ (p - k) * inv[b]

        inv[i] Ξ (p - ?p / i?) * inv[p % i]

所以      inv[i] = (p - ?p / i?) * inv[p %i] % p

装模作样来个代码。

1 inv[1] = 1;
2 for(int i = 2; i <= n; ++i) inv[i] = inv[mod % i] * (mod - mod / i) % mod;

 

 

线性求阶乘的逆元

其实就是根据inv[i] = inv[i + 1] * (i + 1) % p倒着递推而来。

先用费马小定理求出inv[n]的逆元,然后倒着递推。

 1 ll quickpow(ll a, ll b)
 2 {
 3     a %= mod;
 4     ll ret = 1;
 5     for(; b; b >>= 1, a = a * a % mod) 
 6         if(b & 1) ret = ret * a % mod;
 7     return ret;
 8 }
 9 ll fac[maxn], inv[maxn];
10 void init(int n)
11 {
12     fac[1] = 1;
13     for(int i = 2; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
14     inv[n] = quickpow(fac[n], mod - 2);
15     for(int i = n - 1; i; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
16 }

 

以上是关于逆元板子集的主要内容,如果未能解决你的问题,请参考以下文章

逆元板子

求逆元的板子

乘法逆元的求法(5种)

一些数论的板子

P1680 奇怪的分组(组合数+逆元)

hdu5651 xiaoxin juju needs help (多重集的全排列+逆元)