zoukankan      html  css  js  c++  java
  • Lucas定理详解

    这篇博客是从另一位园友那里存的,但是当时忘了写原文的地址,如果有找到原文地址的请评论联系!

    Lucas定理解决的问题是组合数取模。数学上来说,就是求 (inom n mmod p)。(p为素数)

    这里(n,m)可能很大,比如达到(10^{15}),而(p)(10^9)以内。显然运用常规的阶乘方法无法直接求解,所以引入Lucas定理。

    Lucas定理

    (n)(m)写成(p)进制数的样子(如果长度不一样把短的补成长的那个的长度):
    (n=(a0a1…ak)p)
    (m=(b0b1…bk)p)

    那么:
    (inom n m equiv prod _{i=0}^k inom {a_i} {b_i} mod p)

    证明
    如果把Lucas定理从递归的角度理解,它其实是这样的:
    (n=ap+b,m=cp+d,(b,d<p,a=lfloorfrac{n}{p} floor,c=lfloor frac{m}{p} floor) \ inom n m equiv inom a c * inom b d)

    这个定理的一个很巧妙的证法是通过二项式定理来说明上面的式子是成立的。

    首先,对于任意质数(p),有:
    ((1+x)^pequiv 1+x^pmod p)

    其证明可以由费马小定理((x^p equiv x mod p) |p为素数))直接得出:
    ((1+x)^pequiv 1+x)
    (x^pequiv x)
    所以((1+x)^pequiv 1+x equiv 1+x^p)

    (当然同样也有((a+b)^pequiv a^p+b^p mod p),具体为什么你可以拆开前面的式子,将其除 (a^p)(b^p) 项外的所有项的系数好好研究一下(其实就是杨辉三角的第p层),可以发现把对称项系数分别合并后都能整除(p)

    利用这个性质,我们证明Lucas定理:
    (egin{aligned} (1+x)^n&=(1+x)^{lfloor frac{n}{p} floor *p}(1+x)^b \ &=(1+x^p)^{lfloor frac{n}{p} floor}(1+x)^b \ &=sum _{i=0}^kinom {lfloor frac{n}{p} floor} ix^{pi}sum _{j=0}^kinom b jx^j end{aligned})

    考察等式左右两边xmxm的系数,可以发现:
    (egin{aligned} 左边&=inom n m \ 右边&=inom {lfloor frac{n}{p} floor} iinom b j,(pi+j=m,j<p) \ &=inom {lfloor frac{n}{p} floor} {lfloor frac{m}{p} floor} inom b d end{aligned})

    所以上面的式子成立,证明完毕。

    如果不算预处理什么的,算法时间复杂度为(O(log_pn))。如果能够支持预处理,那么就加一个(O(p)),要不就用快速幂,乘上(O(logp))

  • 相关阅读:
    Python基础篇【第二篇】:运算符
    python详细安装pip教程
    工作区和暂存区
    linux日常命令记录
    git-版本回退
    git-版本状态
    git-创建版本库
    Python核心编程读笔 8: 文件和输入输出
    Python核心编程读笔 7: 条件和循环
    Python核心编程读笔 6: 映射和集合类型
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/lucas.html
Copyright © 2011-2022 走看看