[学习笔记]组合数取模的几种求法

一、引入

给定 n n m m p p ,求:
( n m )   m o d   p \binom nm\bmod p
其中 ( n m ) \binom nm 为组合数,表示 n n 个元素中选出 m m 个的方案数。
即:
( n m ) = n ! m ! × ( n m ) ! \binom nm=\frac{n!}{m!\times(n-m)!}
特殊地,我们规定 ( n 0 ) = 1 \binom n0=1 且当 n < m n<m ( n m ) = 0 \binom nm=0

二、 n , m 3 , 000 n,m\le 3,000

( n m ) = ( n 1 m ) + ( n 1 m 1 ) \binom nm=\binom {n-1}m+\binom{n-1}{m-1}
(1)组合意义:
考察 n n 个元素中的最后一个元素是否被选出。
如果没有被选出,那么前面的 n 1 n-1 个元素必须选出 m m 个,即 ( n 1 m ) \binom {n-1}m
如果被选出,那么前面的 n 1 n-1 个元素必须选出 m 1 m-1 个,即 ( n 1 m 1 ) \binom {n-1}{m-1}
(2)数学推导:
( n 1 m ) + ( n 1 m 1 ) = ( n 1 ) ! m ! × ( n 1 m ) ! + ( n 1 ) ! ( m 1 ) ! × ( n m ) ! \binom{n-1}m+\binom{n-1}{m-1}=\frac{(n-1)!}{m!\times(n-1-m)!}+\frac{(n-1)!}{(m-1)!\times(n-m)!}
= ( n 1 ) ! × ( n m ) + ( n 1 ) ! × m m ! × ( n m ) ! = n ! m ! × ( n m ) ! = ( n m ) =\frac{(n-1)!\times(n-m)+(n-1)!\times m}{m!\times(n-m)!}=\frac{n!}{m!\times(n-m)!}=\binom nm
(3)生成函数:
根据二项式定理 ( a + b ) n = i = 0 n ( n i ) a i b n i (a+b)^n=\sum_{i=0}^n\binom nia^ib^{n-i} ,数列
( n 0 ) , ( n 1 ) , ( n 2 ) , . . . , ( n n ) \binom n0,\binom n1,\binom n2,...,\binom nn
的生成函数为 ( 1 + x ) n (1+x)^n
于是 ( n m ) \binom nm 就是 ( 1 + x ) n (1+x)^n m m 次项。
( F ( x ) ) k (F(x))_k 表示多项式 F ( x ) F(x) k k 次项。
则:
( n 1 m ) + ( n 1 m 1 ) = ( ( 1 + x ) n 1 ) m + ( ( 1 + x ) n 1 ) m 1 \binom{n-1}m+\binom{n-1}{m-1}=((1+x)^{n-1})_m+((1+x)^{n-1})_{m-1}
= ( ( 1 + x ) n 1 ) m + ( x ( 1 + x ) n 1 ) m = ( ( 1 + x ) n ) m = ( n m ) =((1+x)^{n-1})_m+(x(1+x)^{n-1})_m=((1+x)^n)_m=\binom nm
利用这个公式进行 O ( n m ) O(nm) 的递推,可以预处理出 i [ 0 , n ] i\in[0,n] j [ 0 , m ] j\in[0,m] 范围内所有的 ( i j ) \binom ij
n n 达到 1 0 9 10^9 甚至 1 0 18 10^{18} 级别但 m m 只有 100 100 级别时,可以用矩阵乘法优化这个递推,复杂度可以做到 O ( m 3 log n ) O(m^3\log n)

三、 n , m 1 0 7 n,m\le 10^7 n , m < p n,m<p p p 是质数

直接使用组合数的通项公式:
( n m ) = n ! m ! × ( n m ) ! \binom nm=\frac{n!}{m!\times (n-m)!}
预处理阶乘极其逆元即可。
逆元线性递推公式:
x 1 ( p p x ) × ( p   m o d   x ) 1 (   m o d   p ) x^{-1}\equiv (p-\lfloor\frac px\rfloor)\times(p\bmod x)^{-1}(\bmod p)
( x ! ) 1 = i = 1 x i 1 (x!)^{-1}=\prod_{i=1}^xi^{-1}
复杂度 O ( max ( n , m ) ) O(\max(n,m))

四、 p 1 0 7 p\le 10^7 且为质数

Lucas 定理:
( n m ) ( n p m p ) × ( n   m o d   p m   m o d   p ) (   m o d   p ) \binom nm\equiv\binom{\lfloor \frac np\rfloor}{\lfloor \frac mp\rfloor}\times\binom{n\bmod p}{m\bmod p}(\bmod p)
另一种说法:
( n m ) = i = 0 ( n i m i ) (   m o d   p ) \binom nm=\prod_{i=0}^{\infty}\binom{n_i}{m_i}(\bmod p)
其中 n i n_i 表示 p p 进制意义下 n n i i 位的值,最低位为第 0 0 位。
证明:
前面已经提到,数列 ( n 0 ) \binom n0 ( n 1 ) \binom n1 \dots ( n n ) \binom nn 的生成函数是 ( 1 + x ) n (1+x)^n
为了方便讨论,下面多项式的系数都在模 p p 意义下。
我们知道,当 0 < n < p 0<n<p 时:
( p n ) 0 (   m o d   p ) \binom pn\equiv 0(\bmod p)
于是:
( 1 + x ) n 1 + x n (   m o d   p ) (1+x)^n\equiv 1+x^n(\bmod p)
根据 n = n p × p + n   m o d   p n=\lfloor\frac np\rfloor\times p+n\bmod p ,得到:
( 1 + x ) n = ( ( 1 + x ) p ) n p × ( 1 + x ) n   m o d   p (1+x)^n=((1+x)^p)^{\lfloor\frac np\rfloor}\times(1+x)^{n\bmod p}
( 1 + x p ) n p × ( 1 + x ) n   m o d   p (   m o d   p ) \equiv(1+x^p)^{\lfloor\frac np\rfloor}\times(1+x)^{n\bmod p}(\bmod p)
利用二项式定理展开:
i = 0 n ( n i ) x i ( i = 0 n p ( n p i ) ( x p ) i ) ( i = 0 n   m o d   p ( n   m o d   p i ) x i ) \sum_{i=0}^n\binom nix^i\equiv(\sum_{i=0}^{\lfloor\frac np\rfloor}\binom {\lfloor\frac np\rfloor}i(x^p)^i)(\sum_{i=0}^{n\bmod p}\binom{n\bmod p}ix^i)
式子左边的 m m 次项为 ( n m ) \binom nm
式子右边是两个多项式的卷积,但是第一个多项式只有 p p 的倍数次项不为 0 0 ,第二个多项式大于等于 p p 的项全部为 0 0
由于将整数 m m 表示成 m = k p + c m=kp+c c < p c<p 的方式是唯一的,即 k = m p k=\lfloor\frac mp\rfloor c = m   m o d   p c=m\bmod p
所以这两个多项式卷积的 m m 次项系数为第一个多项式的 m p \lfloor\frac mp\rfloor 项系数乘上第二个多项式的 m   m o d   p m\bmod p 次项系数。
即式子右边的 m m 次项为 ( n p m p ) × ( n   m o d   p m   m o d   p ) \binom{\lfloor\frac np\rfloor}{\lfloor\frac mp\rfloor}\times\binom{n\bmod p}{m\bmod p}
得证。
先预处理出 [ 0 , min ( max ( n , m ) , p 1 ) ] [0,\min(\max(n,m),p-1)] 内的阶乘及其逆元。
然后根据 Lucas 定理递归下去,当 n , m n,m 都小于 p p 时停止递归。
复杂度 O ( min ( max ( n , m ) , p 1 ) + log p ) O(\min(\max(n,m),p-1)+\log p)

五、 n , m 1 0 7 n,m\le 10^7 p 1 0 9 p\le 10^9

这时候 p p 不一定是质数。
先把 n ! , m ! , ( n m ) ! n!,m!,(n-m)! 分解质因数。
阶乘分解质因数的方法: n ! n! 中质因子 k k 的出现次数为:
i = 1 n k i \sum_{i=1}^{\infty}\lfloor\frac n{k^i}\rfloor
然后 ( n m ) \binom nm 中质因子 k k 的出现次数为 n ! n! k k 的出现次数减去 m ! m! k k 的次数再减去 ( n m ) ! (n-m)! k k 的次数。
复杂度 O ( n + m ) O(n+m)

六、 n , m 1 0 9 n,m\le 10^9 p i c i 1 0 6 p_i^{c_i}\le 10^6

其中 p i p_i c i c_i 分别表示 p p 的质因子和 p i p_i p p 中的次数。
扩展 Lucas 定理。
先把 p p 分解质因数:
p = i = 1 s p i c i p=\sum_{i=1}^sp_i^{c_i}
如果我们求出了对于每个 i i ( n m )   m o d   p i c i \binom nm\bmod p_i^{c_i} 的值,就可以使用中国剩余定理合并,得到 ( n m ) \binom nm
下面的关键就是求 ( n m )   m o d   p i c i \binom nm\bmod p_i^{c_i}
由于 p i p_i 是质数,所以我们只需要先使用阶乘分解算出 ( n m ) \binom nm p i p_i 的次数 c n t cnt
分别求出 n ! n! m ! m! ( n m ) ! (n-m)! 去掉所有质因子 p i p_i 之后模 p i c i p_i^{c_i} 的结果,记为:
F ( n ) , F ( m ) , F ( n m ) F(n),F(m),F(n-m)
那么:
( n m ) F ( n ) × F ( m ) 1 × F ( n m ) 1 × p i c n t (   m o d   p i c i ) \binom nm\equiv F(n)\times F(m)^{-1}\times F(n-m)^{-1}\times p_i^{cnt}(\bmod p_i^{c_i})
下面重点讨论求 F ( n ) F(n)
i i 0 0 p i c i 1 p_i^{c_i}-1 预处理出 N ( i ) N(i) 表示 1 1 i i 所有不是 p i p_i 的倍数的数的积模 p i c i p_i^{c_i}
可以递归求 F ( n ) F(n) 。递归边界为 n < p i n<p_i ,这时 F ( n ) = N ( n ) F(n)=N(n)
否则取出 1 1 n n 中所有 p i p_i 的倍数先处理,可以得出这就是 F ( n p i ) F(\lfloor\frac n{p_i}\rfloor)
然后考虑 1 1 n n 内每个长度为 p i c i p_i^{c_i} 的循环节,这个循环节内数的乘积是一样的,
所以这一部分的贡献为:
N ( p i c i 1 ) n p i c i N(p_i^{c_i}-1)^{\lfloor\frac n{p_i^{c_i}}\rfloor}
还有剩下的 n   m o d   p i c i n\bmod p_i^{c_i} 个数无法构成循环节,所以最后一部分的贡献为 N ( n   m o d   p i c i ) N(n\bmod p_i^{c_i})
所以:
F ( n ) = { F ( n p i ) × N ( p i c i 1 ) n p i c i × N ( n   m o d   p i c i ) n p i N ( n ) n < p i F(n)=\begin{cases}F(\lfloor\frac n{p_i}\rfloor)\times N(p_i^{c_i}-1)^{\lfloor\frac n{p_i^{c_i}}\rfloor}\times N(n\bmod p_i^{c_i})&n\ge p_i\\N(n)&n<p_i\end{cases}
一个有趣的栗子: n = 19 , p i = 3 , c i = 2 n=19,p_i=3,c_i=2
19 ! = ( 1 × 2 × 4 × 5 × 7 × 8 ) × ( 10 × 11 × 13 × 14 × 16 × 17 ) 19!=(1\times2\times4\times5\times7\times8)\times(10\times11\times13\times14\times16\times17) × 19 × 3 6 × 6 ! \times19\times3^6\times 6!
( 1 × 2 × 4 × 5 × 7 × 8 ) 2 × 19 × 3 6 × 6 ! (   m o d   9 ) \equiv(1\times2\times4\times5\times7\times8)^2\times19\times3^6\times 6!(\bmod 9)
上面 1 × 2 × 4 × 5 × 7 × 8 1\times 2\times 4\times 5\times 7\times 8 即为 N ( 9 1 ) N(9-1) 6 ! 6! 可以递归下去, 19 19 即为剩余的 N ( 19   m o d   9 ) = N ( 1 ) N(19\bmod 9)=N(1)
复杂度比较迷……

七、 n , m 1 0 9 n,m\le 10^9 p p 是 int 范围内的质数

如果有某个 dalao 会复杂度比较优秀的做法,请在评论区发表。

猜你喜欢

转载自blog.csdn.net/xyz32768/article/details/83651221