「笔记」$exlucas$

\(exlucas\)
用于计算任意模数的组合数。

一般情况下我们要求的是:

\[\binom{n}{m}\ mod\ P,n<1e9,m<1e9 \]

我们设:\(P=\_*p^k,p^k<1e5\)
注意到由于各个质因子之间互质而且\(p^k\)很小。
那么我们可以利用\(CRT\)来处理这种情况,直接计算:

\[\binom{n}{m}\ mod\ p^k \]

怎么做呢?
首先我们不能直接用\(lucas\)算这个组合数的原因是\(p^k\)不是质数。
其次我们不能直接暴力来计算这个组合数的原因是\(n,m\)数据范围过大。
再退一步讲,由于分子分母上下可以消去\(p\)的次幂,我们可能会将本来互质的部分模为0。
由于存在一种\(log_p\)求阶乘中含有某个数的次幂的方法。
也就是说需要计算互质的部分了,因为这部分存在逆元,剩下含有\(p\)的部分直接\(log_p\)处理出来即可。
我们实际上需要求得就是:

\[\prod\limits_{i=1,i\perp p}^{n}i \]

我们发现:

\[\prod\limits_{i=1,i\perp p}^{p^k-1}\equiv\prod\limits_{i=1\perp p}^{p^k-1}(i+tp^k)\ mod\ p^k \]

那么这样的话存在的

\[\prod\limits_{i=1,i\perp p}^{p^k-1} \]

就只有\(\lfloor\frac{n}{p^k}\rfloor\)
直接快速幂乘起来就可以了。
剩下的\(n\ mod\ p^k\)的那一部分小于\(p^k\)可以直接预处理出来(如果只求求一个组合数就暴力算就可以)。
然后整理出除去\(p\)的部分剩下的互质部分的乘积,发现这是另外一个阶乘\(\lfloor\frac{n}{p}\rfloor!\)直接递归处理即可。
这样的话就得到了互质部分的阶乘。
直接乘起来或者求逆元并顺手计算出含\(p\)的部分即可。

posted @ 2020-01-04 17:17  Lrefrain  阅读(973)  评论(0编辑  收藏  举报