文章目录 1. 关于n!的一个问题2. 组合数的计算2.1 如何计算 C n m C_n^m Cnm方法一:通过定义式直接计算方法二:通过递推公式计算⭐⭐⭐⭐⭐方法三:通过定义式的变形来计算2.2 如何计算 C n m % p C_n^m \% p Cnm%p方法一:通过递推公式计算⭐⭐⭐⭐⭐参考文档 1. 关于n!的一个问题 我们来讨论一个关于 n! 的一个问题——求n!中有多少个质因子p。 这个问题是什么意思呢?举个例子,6!=1x2x3x4x5x6,于是6!中有4个质因子2,因为2、4、6中各有1个2、2个2、1个2;而6!中有两个质因子3,因为3、6中均各有1个3。 对于这个问题,直观的想法是计算从1~n的每个数各有多少个质因子p,然后将结果累加,时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),如下面的代码: //计算n!中有多少个质因子p int cal(int n,int p){ int ans = 0; for(int i=2;i<=n;++i){ //遍历2~n int temp = i; while(temp % p == 0){ //只要temp还是p的倍数 ans++; //p的个数加1 temp /= p; //temp除以p } } return ans; } 但是这种做法对n很大的情况(例如n是 1 0 18 10^{18} 1018)是无法承受的,我们需要寻求速度更快的方法。 现在考虑10!中质因子2的个数,如图5-2所示: 显然10!中有因子 2 1 2^1 21的数的个数为5,有因子 2 2 2^2 22的数的个数为2,有因子 2 3 2^3 23的数的个数为1,因此10!中质因子2的个数为 5 + 2 + 1 = 8。 仔细思考便可以发现此过程可以推广为:n!中有 ( n p + n p 2 + n p 3 + . . . ) (\frac{n} {p} + \frac{n} {p^2} + \frac{n} {p^3} + ...) (pn+p2n+p3n+...)个质因子p,其中除法均为向下取整。于是便得到了 O ( l o g n ) O(logn) O(logn) 的算法,代码如下: //计算n!中有多少个质因子p int cal(int n,int p){ int ans = 0; wh