① 1 <= m <= n <= 5000

1.1 如果 m,n非常小以至于C(n,m)都不会爆long long ,那么我们直接上杨辉三角去解

1.2 如果 n , m 比较大,但是要求取模,还是用杨辉三角去解。

1.3 如果 保证了最终的结果不爆long long ,那么我们可以用记忆化搜索 + 杨辉三角.

注意:最好要用记忆化搜索去写,用一行一行刷表式的去递推会造成中间的爆long long,导致程序不规范.

用记忆化搜索(递归)不会造成爆long long 的原理:C(n,m) = C(n-1,m-1) + C(n - 1 , m).如果大问题不爆long long. 那么小问题一定不会爆long long ,那么我们就自顶向上的用记忆化搜索去写。


②  n <= 1e6(也可以更大),单点询问,不取模,保证结果不会爆long long

思路:

有了这个公式,我们动态维护一个ans表示当前的组合数,对于相邻的下一个组合数.设fz = n - x + 1.fm = x;

令A = gcd(fm,ans),用A除去fm和ans.

令B = gcd(fz,fm),用B除去fm和fz.

剩下来的fm一定是1.因为任意组合数C(n,x)是整数,所以ans * fz 一定能够整除fm.

这样以来可以保证只要结果不爆long long,那么计算过程中也不会爆long long.(这个计算的过程实际上是先算C(n,1),然后转移的算C(n,2) .... 再算到C(n,m),这个过程中ans一定是递增的).

复杂度:O(nlogn)

③ n <= 1e6.单点查询,要求在模mod意义下的值.

思路:

分母分子分别求出来,对分母求逆元再相乘得结果.复杂度O(n).(这里可以有个优化,O(n)计算阶乘的逆元).

④ n ,m 极大(通常远大于mod),要求在模mod意义下的值.(mod <= 1e5 且保证mod是质数).

思路:

引入Lucas定理,递归求解.复杂度:

板子:

http://acm.hdu.edu.cn/viewcode.php?rid=32753896

⑤跟上述一样,但mod不一定是质数.

引入扩展Lucas定理.待补.