这篇博客是从另一位园友那里存的,但是当时忘了写原文的地址,如果有找到原文地址的请评论联系!
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))。