lucas定理、拓展lucas定理学习小结

lucas定理

正题

首先,这玩意就是下面这个式子:
C m n % p = C m / p n / p ∗ C m % p n % p % p C_m^n\%p=C_{m/p}^{n/p}*C_{m\%p}^{n\%p}\%p Cmn%p=Cm/pn/pCm%pn%p%p
当且仅当 p p p为质数。

当然,还有一个形式:
首先把n写成一个p进制下的东东: n = ∑ a i ∗ p i n=\sum a_i*p^i n=aipi
在把m写成一个p进制下的东东: m = ∑ b j ∗ p j m=\sum b_j*p^j m=bjpj
然后
C m n = Π C b i a i % p C_m^n=\Pi C_{b_i}^{a_i}\%p Cmn=ΠCbiai%p

证明,由于则不是主要内容,所以在此不展开了。自己上百度。
或者这里有一张图:(转的)
在这里插入图片描述

其实是太懒了
在这里插入图片描述

拓展lucas定理

前言

这个东东是解决 C m n % p C_m^n\%p Cmn%p其中p不为质数的情况的。
其实和上面的lucas做法没有半点关系。

前置姿势

中国剩余定理、拓展gcd
没了。

中国剩余定理:(百度百科)
在这里插入图片描述
exgcd:(百度百科)
在这里插入图片描述

正文

直接求解 C m n % P C_m^n\%P Cmn%P我们需要两个条件,一个是能够快速求出 n ! n! n,一个是能快速求出逆元。
然而当n和m都奇大无比时, 且p不为质数。那么就很头痛了。

然后拓展lucas定理(其实都可以不必叫定理了)就可以比较好地解决这个问题。
而这也不是万能的,lucas定理可以运用的前提是p这个合数分解质因数不能是一个巨大的质数乘上一个巨小的质数。

当然,这个可以当做一个判断是否用拓展lucas的一个条件。

讲这么多废话,那么现在开始。

首先,我们要求的东东长这样:
C m n % P = m ! n ! ( m − n ) ! % P C_m^n\%P=\frac{m!}{n!(m-n)!}\%P Cmn%P=n!(mn)!m!%P
首先,我们考虑用拓展中国剩余定理来简化一下这个东东:
{ x ≡ C m n ( % p 1 q 1 ) x ≡ C m n ( % p 2 q 2 ) x ≡ C m n ( % p 3 q 3 ) … … \left\{\begin{matrix}x\equiv C_m^n(\%p_1^{q_1})\\ x\equiv C_m^n(\%p_2^{q_2})\\ x\equiv C_m^n(\%p_3^{q_3})\\ …… \end{matrix}\right. xCmn(%p1q1)xCmn(%p2q2)xCmn(%p3q3)

如果我们求出右式,那么意味着我们可以用中国剩余定理直接合并。

那么问题则转化为求解:
C m n % p q C_m^n\%p^q Cmn%pq
那么我们现在的问题就有两个,一个是如何快速求出阶乘。其次是如何求出这个阶乘的逆元。

求逆元

就以求 n ! n! n!为例
由于 n ! n! n!中有许许多多的因子为 p p p的数。
那么这就不与模数互质了,于是就不能直接套exgcd来求逆元。

怎么办?

考虑从 n ! n! n!把这些 p p p的因子给提出来。
我们原式就变为: n ! p x ∗ p x \frac{n!}{p^x}*p^x pxn!px。其中 x x x是一个未知量,且我们这个x要尽量大使得 n ! p x \frac{n!}{p^x} pxn!里没有 p p p的因子。
我们可以知道,一共有 ⌊ n p ⌋ \lfloor\frac{n}{p}\rfloor pn个这些p的因子,然后他们组成情况为: Π i = 1 ⌊ n p ⌋ i ∗ p \Pi_{i=1}^{\lfloor\frac{n}{p}\rfloor}i*p Πi=1pnip
化简得: ( ⌊ n p ⌋ ) ! ∗ p ⌊ n p ⌋ (\lfloor\frac{n}{p}\rfloor)!*p^{\lfloor\frac{n}{p}\rfloor} (pn)!ppn
那么 n ! n! n!就被我们化成:
( ⌊ n p ⌋ ) ! ∗ p ⌊ n p ⌋ ∗ Π i = 1 n [ i ≢ 0 % p q ] i (\lfloor\frac{n}{p}\rfloor)!*p^{\lfloor\frac{n}{p}\rfloor}*\Pi_{i=1}^n[i\not \equiv 0\%p^q]i (pn)!ppnΠi=1n[i0%pq]i
然鹅 ( ⌊ n p ⌋ ) ! (\lfloor\frac{n}{p}\rfloor)! (pn)!还是有可能有 p p p的因子,因此我们考虑设个 f ( n ) = n ! p x f(n)=\frac{n!}{p^x} f(n)=pxn!
于是原式可以通过递归的方法求解。其中我们的 p ⌊ n p ⌋ p^{\lfloor\frac{n}{p}\rfloor} ppn可以在外面被 p x p^x px给化简掉,所以递归过程忽略。
那么递推式变为:

f ( n ) = f ( ⌊ n p ⌋ ) ∗ Π i = 1 n [ i ≢ 0 % p q ] i f(n)=f(\lfloor\frac{n}{p}\rfloor)*\Pi_{i=1}^n[i\not \equiv 0\%p^q]i f(n)=f(pn)Πi=1n[i0%pq]i

这样我们就可以求出 n ! p x \frac{n!}{p^x} pxn!
然后外面的 p x p^x px我们一样考虑通过递归来求出x的值。
g ( n ) = x g(n)=x g(n)=x
那么递归过程中,每次消去 ⌊ n p ⌋ \lfloor\frac{n}{p}\rfloor pn,且阶乘一样产生贡献。
因此递归式为:
g ( n ) = ⌊ n p ⌋ + g ( ⌊ n p ⌋ ) g(n)=\lfloor\frac{n}{p}\rfloor+g(\lfloor\frac{n}{p}\rfloor) g(n)=pn+g(pn)

至此,我们已经解决了求逆元的问题。

求阶乘
我们发现,上面的递推式中: Π i = 1 n [ i ≢ 0 % p q ] i \Pi_{i=1}^n[i\not \equiv 0\%p^q]i Πi=1n[i0%pq]i长得不是很好看。
但是我们发现,由于是在模 p q p^q pq意义下的东西,所以这玩意是有周期的。
怎么理解?
比如: 1 、 2 、 4 、 5 、 7 、 8 、 10 、 11 、 13 、 14 、 16 、 17 1、2、4、5、7、8、10、11、13、14、16、17 124578101113141617其中 p = 3 , q = 2 p=3,q=2 p=3,q=2
(去除了有因子3的数)
我们发现, 1 ∗ 2 ∗ 4 ∗ 5 ∗ 7 ∗ 8 1*2*4*5*7*8 124578 10 ∗ 11 ∗ 13 ∗ 14 ∗ 16 ∗ 17 10*11*13*14*16*17 101113141617在模意义下是相同的。
那么我们就可以只算出一个周期的值,然后再把这些周期值快速幂乘起来。
然后可能剩下一小段,那么由于比较小,所以直接暴力乘起来即可。

Π i = 1 n [ i ≢ 0 % p q ] i = ( Π i = 1 p q [ i ≢ 0 % p q ] i ) ⌊ n p ⌋ ∗ ( Π i = p q ∗ ⌊ n p ⌋ n [ i ≢ 0 % p q ] i ) \Pi_{i=1}^n[i\not \equiv 0\%p^q]i=(\Pi_{i=1}^{p^q}[i\not \equiv 0\%p^q]i)^{\lfloor\frac{n}{p}\rfloor}*(\Pi_{i=p^q*\lfloor\frac{n}{p}\rfloor}^{n}[i\not \equiv 0\%p^q]i) Πi=1n[i0%pq]i=(Πi=1pq[i0%pq]i)pn(Πi=pqpnn[i0%pq]i)

代码

(看例题)

例题

luoguP4720 【模板】扩展卢卡斯
jzoj3214. 【SDOI2013】方程

参考资料

https://blog.csdn.net/qq_30115697/article/details/88942177
https://www.luogu.com.cn/problem/P4720 中的fading题解
各种百度百科

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值