其实写的博客也舍弃了一些内容吧,可能写到这基本就不会更新算法了,快要国赛了,就好好努力吧
解决问题
Lucas 定理用于求解大组合数取模的问题,其中模数必须为素数。正常的组合数运算可以通过递推公式求解,但当问题规模很大,而模数是一个不大的质数的时候,就不能简单地通过递推求解来得到答案,需要用到Lucas定理
当n和m都大于p的时候可以阶乘求,或者n和m很小的时候可以杨辉三角求,当n和m都小于p的时候,用lucas定理
Lucas定理内容
(inom{n}{m}mod p = inom{leftlfloor n/p ight floor}{leftlfloor m/p ight floor}cdotinom{nmod p}{mmod p}/mod p)
观察上述表达式,可知(nmod p)和(mmod p)一定是小于p的数,可以直接求解,(inom{leftlfloor n/p ight floor}{leftlfloor m/p ight floor})可以继续用 Lucas 定理求解。这也就要求p的范围不能够太大,一般在1e5左右。边界条件:当(m = 0)的时候,返回1。
代码就比较简单啦:
int Lucas(int n,int m,int p){
if (m == 0) return 1;
return (C(n % p,m % p,p)*Lucas(n/p,m/p,p)) % p;
}