Lucas 与 ExLucas

本文详细介绍了Lucas定理及其扩展版本ExLucas算法,用于高效计算模意义下的组合数。Lucas定理针对小质数模,而ExLucas算法则适用于任意模数。文章深入探讨了算法原理,包括质因数分解、中国剩余定理应用及逆元求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意:Lucas 定理和扩展 Lucas 算法没有关系。取名“扩展 Lucas”仅仅是因为该算法能解决 Lucas 定理所解决的问题的推广情况。

Lucas(卢卡斯定理)

定理内容

Lucas(卢卡斯定理)是一个用于加快计算小质数模意义下的组合数的定理。

具体地,它能解决形如
(nm) mod p \binom{n}{m} \bmod p (mn)modp
的问题,其中 ppp 为质数。

公式为:
(nm)≡(⌊np⌋⌊mp⌋)(n mod pm mod p)(modp) \binom{n}{m} \equiv \binom{\lfloor\frac{n}{p}\rfloor}{\lfloor\frac{m}{p}\rfloor} \binom{n \bmod p}{m \bmod p} \pmod p (mn)(pmpn)(mmodpnmodp)(modp)

证明

首先证明一个式子
(1+x)p≡1+xp(modp) (1+x)^p \equiv 1+x^p \pmod p (1+x)p1+xp(modp)
直接把左边二项式展开,得到
1+(p1)x+(p2)x2+⋯+(pp)xp 1+\binom{p}{1}x+\binom{p}{2}x^2+\cdots+\binom{p}{p}x^p 1+(1p)x+(2p)x2++(pp)xp
注意到 ppp 是质数,所以无法在组合数分母上被约去,因此第二项到第 ppp 项都是 ppp 的倍数。因此上式成立。

n=k1p+c1n=k_1p+c_1n=k1p+c1m=k2p+c2m=k_2p+c_2m=k2p+c2

考虑 (1+x)n(1+x)^n(1+x)n。其在模 ppp 意义下有如下等式:
(1+x)n=(1+x)k1p+c1=(1+x)k1p(1+x)c1=(1+xp)k1(1+x)c1 \begin{aligned} & (1+x)^n \\ = & (1+x)^{k_1p+c_1} \\ = & (1+x)^{k_1p} (1+x)^{c_1} \\ = & (1+x^p)^{k_1}(1+x)^{c_1} \\ \end{aligned} ===(1+x)n(1+x)k1p+c1(1+x)k1p(1+x)c1(1+xp)k1(1+x)c1
展开这个式子,考察 xmx^mxm 项。

(1+x)n(1+x)^n(1+x)n 中其系数为 (nm)\binom{n}{m}(mn)。在 (1+xp)k1(1+x)c1(1+x^p)^{k_1}(1+x)^{c_1}(1+xp)k1(1+x)c1 中,次数分解为 k2p+c2k_2p+c_2k2p+c2

分别从两个二项式中提取次数,可得系数为
(k1k2)(c1c2) \binom{k_1}{k_2}\binom{c_1}{c_2} (k2k1)(c2c1)
于是
(nm)≡(k1k2)(c1c2)(modp) \binom{n}{m} \equiv \binom{k_1}{k_2}\binom{c_1}{c_2} \pmod p (mn)(k2k1)(c2c1)(modp)

ExLucas(扩展卢卡斯)

简介

ExLucas(Extended Lucas,扩展卢卡斯)是一个用于加快计算小模数下的模意义组合数的算法。

具体地,它能解决形如
(nm) mod p \binom{n}{m} \bmod p (mn)modp
的问题,其中 ppp 不一定是质数。

算法的核心是利用质因数分解与中国剩余定理,将问题转化为质数幂次模意义下的计算,然后利用式子进行问题规模的缩小并递归求解。

算法与原理

流程与原理

令模数为 ppp,其质因数分解 p=p1α1p2α2⋯p=p_1^{\alpha_1}p_2^{\alpha_2}\cdotsp=p1α1p2α2

我们求解如下几个方程
{(nm)≡a1(modp1α1)(nm)≡a2(modp2α2)⋯ \left\{ \begin{aligned} &\binom{n}{m} \equiv a_1 \pmod {p_1^{\alpha_1}} \\ &\binom{n}{m} \equiv a_2 \pmod {p_2^{\alpha_2}} \\ &\cdots \end{aligned} \right. (mn)a1(modp1α1)(mn)a2(modp2α2)
得出所有 aia_iai 后,用 CRT 合并即可求出答案。以下我们只考虑解决
(nm) mod Pk \binom{n}{m} \bmod P^k (mn)modPk
其中 PPP 为质数。

考虑正常计算组合数的方法:
(nm)=n!m!(n−m)! \binom{n}{m} = \frac{n!}{m!(n-m)!} (mn)=m!(nm)!n!
无法在此处使用该方法,因为逆元可能不存在。

一个数在模意义下存在逆元的充要条件是其与模数互质。因此我们考虑把每个数的模数因子都提出去计算,这样就会互质,就可以求逆元了。

于是令 f(x)f(x)f(x)x!x!x!PPP 因子个数,有
(nm)≡n!Pf(n)m!Pf(m)(n−m)!Pf(n−m)Pf(n)−f(m)−f(n−m)(modPk) \binom{n}{m} \equiv \frac{\frac{n!}{P^{f(n)}}}{\frac{m!}{P^{f(m)}}\frac{(n-m)!}{P^{f(n-m)}}} P^{f(n)-f(m)-f(n-m)} \pmod {P^k} (mn)Pf(m)m!Pf(nm)(nm)!Pf(n)n!Pf(n)f(m)f(nm)(modPk)
于是问题转化为求
x!Pf(x) mod Pk \frac{x!}{P^{f(x)}} \bmod P^k Pf(x)x!modPk
xxx 及以下所有 PPP 的倍数提出在外:
x!=(P×2P×⋯ )(1×2×⋯ ) x! = (P\times 2P\times \cdots)(1 \times 2 \times \cdots) x!=(P×2P×)(1×2×)
提出 PPP
x!=P⌊xP⌋(⌊xP⌋)!(1×2×⋯ ) x!=P^{\lfloor\frac{x}{P}\rfloor} (\lfloor\frac{x}{P}\rfloor)! (1\times 2 \times \cdots) x!=PPx(Px)!(1×2×)
后面的 (1×2×⋯ )(1 \times 2 \times \cdots)(1×2×),其在模 PkP^kPk 意义下显然有周期。

具体地,该式实际形式为
(1×2×⋯×(Pk−1)×(Pk+1)×(Pk+2)×⋯ ) (1\times 2\times \cdots \times (P^k-1) \times (P^k+1) \times (P^k+2) \times \cdots) (1×2××(Pk1)×(Pk+1)×(Pk+2)×)
而在模 PkP^kPk 意义下,其等同于
(1×2×⋯×(Pk−1)×1×2×⋯ ) (1\times 2\times \cdots \times (P^k-1) \times 1 \times 2 \times \cdots) (1×2××(Pk1)×1×2×)
我们把该式写成公式化表达
x!≡P⌊xP⌋(⌊xP⌋)!(∏i=1,P∤iPki)⌊xPk⌋(∏i=1,P∤ix mod Pki)(modPk) x! \equiv P^{\lfloor\frac{x}{P}\rfloor} (\lfloor\frac{x}{P}\rfloor)! (\prod_{i=1,P\nmid i}^{P^k} i)^{\lfloor\frac{x}{P^k}\rfloor}(\prod_{i=1,P\nmid i}^{x \bmod P^k} i) \pmod {P^k} x!PPx(Px)!(i=1,PiPki)Pkx(i=1,PixmodPki)(modPk)
最后那两个部分都是可以暴力的,而 (⌊xP⌋)!(\lfloor\frac{x}{P}\rfloor)!(Px)! 可以递归求解。

然后考察 f(x)f(x)f(x) 怎么求。注意到一个方法是先筛选所有至少有一个 PPP 因子的数,然后筛选所有至少有两个 PPP 因子的数,依此类推。这个过程就是不断找一个数以内 PPP 的倍数的过程,公式化为下式:
f(x)=f(⌊xP⌋)+⌊xP⌋ f(x) = f(\lfloor\frac{x}{P}\rfloor)+\lfloor\frac{x}{P}\rfloor f(x)=f(Px)+Px
边界为 f(x)=0 (x<P)f(x)=0 \ (x<P)f(x)=0 (x<P)

通过这个式子,我们也可以直接写出 g(x)=x!Pf(x)g(x)=\frac{x!}{P^{f(x)}}g(x)=Pf(x)x! 的递归表达式:
g(x)≡g(⌊xP⌋)(∏i=1,P∤iPki)⌊xPk⌋(∏i=1,P∤ix mod Pki)(modPk) g(x) \equiv g(\lfloor\frac{x}{P}\rfloor) (\prod_{i=1,P\nmid i}^{P^k} i)^{\lfloor\frac{x}{P^k}\rfloor}(\prod_{i=1,P\nmid i}^{x \bmod P^k} i) \pmod {P^k} g(x)g(Px)(i=1,PiPki)Pkx(i=1,PixmodPki)(modPk)
最后就是 Pf(n)−f(m)−f(n−m)P^{f(n)-f(m)-f(n-m)}Pf(n)f(m)f(nm) 的求解了。注意到 fff 的递归式,直接求解就是 O(log⁡Pn)O(\log_P n)O(logPn) 的。

总结:

  1. 首先将 ppp 质因数分解为质数次幂,对每个质数次幂作为模数分别求解。
  2. n!n!n!m!m!m!(n−m)!(n-m)!(nm)! 使用上述方法求 ggg。递归下去,层内暴力算乘积。
  3. 计算 g(m)g(m)g(m)g(n−m)g(n-m)g(nm) 的逆元,利用递归式计算 f(n),f(m),f(n−m)f(n),f(m),f(n-m)f(n),f(m),f(nm) 求解。
  4. 将每个结果用 CRT 合并。

时间复杂度

第一步复杂度 O(p)O(\sqrt p)O(p)。如果预线性筛出最小质因子可以做到 O(log⁡p)O(\log p)O(logp),不过瓶颈不在这,没必要。

第二步总复杂度 O(∑Plog⁡PnPk)O(\sum_P \log_P n P^k)O(PlogPnPk),上界是 O(plog⁡n)O(p\log n)O(plogn)

第三步总复杂度 O(∑P(log⁡Pn+log⁡n))O(\sum_P (\log_P n + \log n))O(P(logPn+logn)),上界是 O(log⁡plog⁡n)O(\log p\log n)O(logplogn)

最后一步复杂度 O(log⁡2p)O(\log^2 p)O(log2p)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值