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

    Lucas定理解决的问题是组合数取模。数学上来说,就是求:

    [inom n mmod p ]

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

    Lucas定理

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

    [n=(a_0a_1dots a_k)_p \ m=(b_0b_1dots b_k)_p ]

    那么:

    [inom n mequiv prod _{i=0}^kinom {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 mequiv inom a c*inom b d ]

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

    首先,对于任意质数(p),有:

    [(1+x)^pequiv 1+x^pmod p ]

    证明可以由费马小定理直接得出:

    [(1+x)^pequiv 1+xequiv1+x^p ]

    (当然同样也有((a+b)^pequiv a^p+b^pmod 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} ]

    考察等式左右两边(x^m)的系数,可以发现:

    [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(lop_pn)),如果不算预处理什么的。如果能够支持预处理,那么就加一个(O(p)),要不就用快速幂,乘上(O(logp))

    拓展

    求解(p)不是质数的情况。

    一个很简单的做法就是把(p)分解成多个不同素数的幂相乘,由于是多个不同素数的幂,所以可以直接运用中国剩余定理将答案合并。所以现在问题就转化成,(p)为素数,求:

    [inom n mmod p^q ]

    在这种情况下,使用阶乘的方法就好。

    [inom n m=frac{n!}{m!(n-m)!} ]

    所以问题就变成了快速求(n!mod p^q)

    一个十分经典的例子是:(19!mod 3^2)

    [egin{aligned} 19!&=1*2*3*cdots *17*18*19 \ &=1*2*4*5*7*8*10*11*13*14*16*17*19*(3*6*9*12*15*18) \ &=(1*2*4*5*7*8)*(10*11*13*14*16*17)*19*3^6*(1*2*3*4*5*6) end{aligned} ]

    可以注意到,我们把(p)的倍数提取出来,并且把它们都提出一个(p),那么剩下的又变成了一个阶乘,可以递归计算。前面的部分是(p^q)以内循环的,即(1*2*4*5*7*8equiv10*11*13*14*16*17*19mod 3^2),所以只用算一个,快速幂一下即可。中间的那一项就直接在求组合数的时候相减即可。多出来的非循环的部分一定小于(p^q),所以暴力即可。求一个(n!mod p^q)的复杂度为(O(p^qlog_2n(log_pn-q)))

    所以拓展情况带上CRT的总复杂度为(O(p^qlog_2n(log_pn-q)+nlog_2p))

  • 相关阅读:
    sortColors
    搜索二维矩阵
    矩阵置零
    求解最大子数组的和
    length of the longest substring without repeating character
    求解最大回文子字符串
    求两数的和
    验证回文串的一点解题思路
    fiddler-10-结合 Mock.js 伪接口数据进行测试(下)
    fiddler-9-结合 Mock.js 伪接口数据进行测试(上)
  • 原文地址:https://www.cnblogs.com/owenyu/p/6724560.html
Copyright © 2011-2022 走看看