Lucas 与 ExLucas

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

Lucas(卢卡斯定理)

定理内容

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

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

公式为:
( n m ) ≡ ( ⌊ n p ⌋ ⌊ m p ⌋ ) ( n   m o d   p m   m o d   p ) ( m o d p ) \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 + x p ( m o d p ) (1+x)^p \equiv 1+x^p \pmod p (1+x)p1+xp(modp)
直接把左边二项式展开,得到
1 + ( p 1 ) x + ( p 2 ) x 2 + ⋯ + ( p p ) x p 1+\binom{p}{1}x+\binom{p}{2}x^2+\cdots+\binom{p}{p}x^p 1+(1p)x+(2p)x2++(pp)xp
注意到 p p p 是质数,所以无法在组合数分母上被约去,因此第二项到第 p p p 项都是 p p p 的倍数。因此上式成立。

n = k 1 p + c 1 n=k_1p+c_1 n=k1p+c1 m = k 2 p + c 2 m=k_2p+c_2 m=k2p+c2

考虑 ( 1 + x ) n (1+x)^n (1+x)n。其在模 p p p 意义下有如下等式:
( 1 + x ) n = ( 1 + x ) k 1 p + c 1 = ( 1 + x ) k 1 p ( 1 + x ) c 1 = ( 1 + x p ) k 1 ( 1 + x ) c 1 \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
展开这个式子,考察 x m x^m xm 项。

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

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

ExLucas(扩展卢卡斯)

简介

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

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

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

算法与原理

流程与原理

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

我们求解如下几个方程
{ ( n m ) ≡ a 1 ( m o d p 1 α 1 ) ( n m ) ≡ a 2 ( m o d p 2 α 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)
得出所有 a i a_i ai 后,用 CRT 合并即可求出答案。以下我们只考虑解决
( n m )   m o d   P k \binom{n}{m} \bmod P^k (mn)modPk
其中 P P P 为质数。

考虑正常计算组合数的方法:
( n m ) = 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! P P P 因子个数,有
( n m ) ≡ n ! P f ( n ) m ! P f ( m ) ( n − m ) ! P f ( n − m ) P f ( n ) − f ( m ) − f ( n − m ) ( m o d P k ) \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 ! P f ( x )   m o d   P k \frac{x!}{P^{f(x)}} \bmod P^k Pf(x)x!modPk
x x x 及以下所有 P P P 的倍数提出在外:
x ! = ( P × 2 P × ⋯   ) ( 1 × 2 × ⋯   ) x! = (P\times 2P\times \cdots)(1 \times 2 \times \cdots) x!=(P×2P×)(1×2×)
提出 P P P
x ! = P ⌊ x P ⌋ ( ⌊ x P ⌋ ) ! ( 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×),其在模 P k P^k Pk 意义下显然有周期。

具体地,该式实际形式为
( 1 × 2 × ⋯ × ( P k − 1 ) × ( P k + 1 ) × ( P k + 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)×)
而在模 P k P^k Pk 意义下,其等同于
( 1 × 2 × ⋯ × ( P k − 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 ⌊ x P ⌋ ( ⌊ x P ⌋ ) ! ( ∏ i = 1 , P ∤ i P k i ) ⌊ x P k ⌋ ( ∏ i = 1 , P ∤ i x   m o d   P k i ) ( m o d P k ) 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)
最后那两个部分都是可以暴力的,而 ( ⌊ x P ⌋ ) ! (\lfloor\frac{x}{P}\rfloor)! (Px)! 可以递归求解。

然后考察 f ( x ) f(x) f(x) 怎么求。注意到一个方法是先筛选所有至少有一个 P P P 因子的数,然后筛选所有至少有两个 P P P 因子的数,依此类推。这个过程就是不断找一个数以内 P P P 的倍数的过程,公式化为下式:
f ( x ) = f ( ⌊ x P ⌋ ) + ⌊ x P ⌋ 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 ! P f ( x ) g(x)=\frac{x!}{P^{f(x)}} g(x)=Pf(x)x! 的递归表达式:
g ( x ) ≡ g ( ⌊ x P ⌋ ) ( ∏ i = 1 , P ∤ i P k i ) ⌊ x P k ⌋ ( ∏ i = 1 , P ∤ i x   m o d   P k i ) ( m o d P k ) 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)
最后就是 P f ( n ) − f ( m ) − f ( n − m ) P^{f(n)-f(m)-f(n-m)} Pf(n)f(m)f(nm) 的求解了。注意到 f f f 的递归式,直接求解就是 O ( log ⁡ P n ) O(\log_P n) O(logPn) 的。

总结:

  1. 首先将 p p p 质因数分解为质数次幂,对每个质数次幂作为模数分别求解。
  2. n ! n! n! m ! m! m! ( n − m ) ! (n-m)! (nm)! 使用上述方法求 g g g。递归下去,层内暴力算乘积。
  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 ( ∑ P log ⁡ P n P k ) O(\sum_P \log_P n P^k) O(PlogPnPk),上界是 O ( p log ⁡ n ) O(p\log n) O(plogn)

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值