算法学习————Lucas定理
其实写的博客也舍弃了一些内容吧,可能写到这基本就不会更新算法了,快要国赛了,就好好努力吧
解决问题
Lucas 定理用于求解大组合数取模的问题,其中模数必须为素数。正常的组合数运算可以通过递推公式求解,但当问题规模很大,而模数是一个不大的质数的时候,就不能简单地通过递推求解来得到答案,需要用到Lucas定理
当n和m都大于p的时候可以阶乘求,或者n和m很小的时候可以杨辉三角求,当n和m都小于p的时候,用lucas定理
Lucas定理内容
\(\binom{n}{m}\bmod p = \binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor}\cdot\binom{n\bmod p}{m\bmod p}/\bmod p\)
观察上述表达式,可知\(n\bmod p\)和\(m\bmod p\)一定是小于p的数,可以直接求解,\(\binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor}\)可以继续用 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;
}