本来没打算学的,既然模拟赛考到了就还是学一下吧
Pre-Knowledge
Brief Introduction
我们都知道,Lucas定理
是当n,m比较大(大于P)时,用来求,其中P为质数的一个工具。它长这样:
把 n 和 m 表示成 P 进制数,对 P进制下的每一位分别计算组合数,最后乘起来。这样递归计算的话就能保证需要求的n,m在P的范围内了
但是当不为质数的时候就需要用到扩展Lucas
了,但其实它和Lucas
没有半毛钱关系
Analysis
把p质因数分解,即分解成P=∏piki的形式,那么只需要分别求出,利用CRT
或ex_CRT
就能合并答案
把组合数展开:
考虑把n!,m!,(n−m)!这三项中含pi的因子提出来,变形得到
其中a1,a2,a3分别表示n!,m!,(n−m)!含pi的次数
解决这个子问题,注意在计算上式的分母时需要用ex_gcd
求逆元
最后一步步往上推就行了
Process
重点在于如何求
先举一个例子吧,假设n=19,p=3,k=2
这里真的随便手玩一下就懂了
19!=1×2×3×4×5×6×7×8×9×10×11×12×13×14×15×16×17×18×19把所有p的倍数的项提出来:
19!=36×(1×2×3×4×5×6)×(1×2×4×5×7×8×10×11×13×14×16×17×19)不难注意到最后一个括号里的数在模pk意义下是不断循环的,即
19!=36×(1×2×3×4×5×6)×(1×2×4×5×7×8)×(10×11×13×14×16×17)×19很显然,(1×2×4×5×7×8)和(10×11×13×14×16×17)在模pk意义下相等
那么
19!=36×6!×(1×2×4×5×7×8)2×19
通过上面这个例子,我们可以形式化地得出以下式子:
其中numi表示不含p因子的数字
考虑每一项的意义以及如何求:
- p⌊pn⌋ :因为最后我们要求,需要除掉pa,因此可以在这里直接不乘这一项
- ⌊pn⌋! :直接递归求解,边界条件是n=0答案为1
- :也就是小于的部分循环了次。可以直接暴力求出,然后做一遍快速幂
- :循环最后会剩下一部分多的,直接暴力乘起来即可
Complexity
瞎分析一波
首先分析一下求解的复杂度
T(n)=T(pn)+O(pk)根据主定理容易得到T(n)=O(pk)
另外,ex_gcd
求逆元那里还有一个的复杂度
总复杂度为
O(∑(piki+logP))Code
还没写