先问一个简单的问题,求:
不保证 $q$ 是质数。$1\le q\le 10^6,1\le m\le n\le 10^{18}$。
这很毒瘤了!我们平常熟知的几个方法,预处理阶乘和阶乘逆元,或者是 Lucas
定理,都需要 $q$ 为质数才能这么干。现在 $q$ 连质数都不是,可咋整呢…
正片开始
主题思路
- 我们用公式 $C_n^m=\dfrac{n!}{m!(n-m)!}$
- 把 $q$ 分解质因数,分解成若干的 $p^k$ 相乘的形式
- 现在假设模数为 $p^k$,求 $C_n^m \pmod {p^k}$
- 用中国剩余定理合并答案
那么,卢卡斯定理呢?引用某神仙写题解时,说过的一句话:
首先,得确定先会扩展欧几里得算法和扩展中国剩余定理。至于卢卡斯定理,那并不重要。
(扩展卢卡斯定理和卢卡斯定理并没有任何关系2333)
对每个质因数求答案
我们发现,$n$ 的范围比 $q$ 要大很多。也就是说,分子分母两个阶乘很可能都是 $0$。
那么就出现了一个想法:我们把分子分母中的含 $p$ 的因子都单独拿出来。
设 $n!$ 中最多包含 $a$ 个 $p$ 因子,$m!$ 和 $(n-m)!$ 中分别包含 $b,c$ 个。设 $f(x)$ 表示把 $x!$ 中的 $p$ 因子都去掉后的值,于是答案等于
然后现在我们要求两个东西:
- $f(x)$ (定义见上)
- $x!$ 中有多少 $p$ 因子,设为 $g(x)$(这个小学就会了吧,$g(x)=g(x/p)+(x/p)$)
那怎么求 $f(x)$ 呢?
第一部分:拿掉所有倍数
先把所有 $p$ 的倍数都拿掉,大概等于:
$[1\times 2\times 3\times …\times (p-1)]\times [(p+1)\times (p+2)\times (p+3)…\times (2p-1)]\times …$
(一直乘到 $x$ 往下最后一个不是 $p$ 的倍数的数)
然后你们就会发现我偷偷的把每 $p-1$ 个数分在了同一个中括号里面。我们称这一个中括号为“一组”。组从 $1$ 开始编号(也就是 $1\times 2\times …\times (p-1)$ 是第 $1$ 组,然后剩下的依次编号)
找一下规律: 第 $x$ 组的积就等于 $[xp-p+1,xp-1]$ 之间的数的积。
然后考虑 $p^k-1$ 这个数,它显然是第 $p^{k-1}$ 组的最后一个。那它下一组,就是以下这些数的乘积:
$p^k+1,p^k+2,… p^k+p-1$。
别忘了我们的 $f(x)$ 模数是 $p^k$ (见上面的式子)。所以,很显然,这些数同余于:
$1,2,…p-1$
这和第一组是一样的了。那就出现了 循环节!
我们设“一节”的积为 $S$,那它就等于第 $1$ 组,第 $2$ 组,…第 $p^{k-1}$ 组中的所有数的乘积。
显然,$x!$ 一共能分出 $\dfrac{x}{p^k}$ 个 $S$。
当然,还有 $x \bmod {p^k}$ 个不完整的“一节”,设为 $R$。暴力计算即可。
这一部分的答案(设为 $A$)就等于 $(S)^{\frac{x}{p^k}} \times R$
那么求 $S$ 和求最后几个不完整的块,就都是 $O(p^k)$ 的了。因为 $q\le 10^6$,所以不会有问题。
第二部分:只考虑 p 的倍数
那这一部分就等于
$p\times 2p \times 3p \times …\times (n/p)p$
然后我们要去掉所有 $p$ 的因子。于是剩下了一个 $(n/p)!$
但是我们发现这个玩意要递归计算…于是这一部分答案为 $f(n/p)$
综上
时间复杂度 $O(p^k\log x)$
中国剩余定理合并答案
什么?你中国剩余定理不会?
额…好的,我会写(gu)博(gu)客(gu)的!
洛谷上的板子代码
1 | // 以下注释中的 ^ 均表示幂 |