Lucas定理
主要用来处理大组合数取模(模数是质数)的问题
内容:C(n,m)=C(n/p,m/p)*C(n%p,m%p)%p (n/p依旧是向下取整)
证明:Lucas定理的另一种表现方式:
C(sp+q,tp+r)≡C(s,t)*C(q,r)(mod p)
首先:1+x^(sp+q)=((1+x)^p)^s*(1+x)^q
所以:(1+x)^(sp+q)≡Σi=0…s C(s,i)x^(i*p)Σ(i=0…q)C(q,i)*x^i (利用二项式定理)
令右式i=t,j=r则右式x^(tp+r)系数为 C(s,t)*C(q,r);
对左式直接使用二项式定理
令左式i=tp+r,则左式x^(tp+r)系数为C(sp+q,tp+r);
所以得证。
关于Lucas定理的扩展:
对于模数p
1.p是素数
2.p不是素数
又可分为(1).分解完质数后每个质因子只出现一次
(2).分解完质数后每个质因子出现不止一次
3.p不是素数但p=m^t(m为素数)
处理方式:
对1 直接运用Lucas定理即可求解
对2(1) 可以运用Lucas求对p的每个质因子的模,再运用中国剩余定理将模数合并(又引出了一个flag)
对2(2) 对出现不止一次的质因子,则每个质因子的n次幂跟3一样处理,然后再运用中国剩余定理合并
对3
因为C(n,m)=n!/(m!(n-m)!)
所以我们可以分为三部分求解:n!%p^t,m!%p^t,(n-m)!%p^t 再逆元就可求解。
·求n!%p^t:
1.求p的幂,即p^(n/p) (快速幂)
2.新的阶乘 即(n/p)! (递归)
3.剩下部分 模p^t意义下以p^t为周期,所以求p^t长度就可。
剩下孤立的数长度不会超过p^t,暴力求解就可。
·关于m!%p^t和(n-m)!%(p^t)
方法大致与上述相同 但因为不互质就无法求逆元,所以应先除去质因子,求出逆元后再乘回去。
补充:
计算n!的质因子p的个数x为:
x=(n/p)+(n/(p^2))+(n/(p^3))+…
递推:f[n]=f[n/p]+n/p; //n/p均为向下取整
题【板】:
hdu 3037[感觉我做的题都还是挺水的]
[这道题是好久以前做的都快不记得题面了]
[也当留个板吧]
//玄学 long long
#include<cstdio>
#include<algorithm>