算法学习————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;
}
posted @ 2021-07-03 17:23  小又又yyyy  阅读(85)  评论(0编辑  收藏  举报