关于组合数取模
对于C(n,m) mod p (m<=n)
1、如果n,m比较,1<=m<=n<=1000,p<=1e9
可以用杨辉三角递推式去解决,用C[n][m]来储存C(n,m)的值,则递推式为:
C[i][j] mod p=(C[i-1][j-1]+C[i-1][j]) mod p(1<=j<=i) C[i][0]=1
2、如果n,m较大(1<=m<=n<=1e18)且p是素数
可以用Lucas定理去解决。
Lucas定理的定义:
如果有两个数n,m可以表示为
n = n k ∗ p k + n k − 1 ∗ p k − 1 + . . . + n 1 ∗ p 1 + n 0 n=n_k*p^k+n_{k-1}*p^{k-1}+...+n_1*p^1+n_0 n=nk∗pk+nk−1∗pk−1+...+n1∗p1+n0
m = m k ∗ p k + m k − 1 ∗ p k − 1 + . . . + m 1 ∗ p 1 + m 0 m=m_k*p^k+m_{k-1}*p^{k-1}+...+m_1*p^1+m_0 m=mk∗pk+mk−1∗pk−1+...+m1∗p1+m0
那么有
C m n ≡ ∏ i = 0 k C m i n i ( m o d p ) C_{m}^{n}\equiv\prod_{i=0}^{k}C_{m_i}^{n_i} \pmod p Cmn≡i=0∏kCmini(modp)要证明Lucas定理,首先证明 C p x ≡ 0 ( m o d p ) C_{p}^{x} \equiv 0 \pmod{p} Cpx≡0(modp)
证:
C p x m o d p = p ! x ! ( p − x ) ! m o d p = p x ∗ ( p − 1 ) ! ( x − 1 ) ! ( p − x ) ! m o d p = p ∗ i n v ( x ) ∗ C p − 1 x − 1 m o d p C_{p}^{x}\bmod p=\frac{p!}{x!(p-x)!}\bmod p=\frac{p}{x}*\frac{(p-1)!}{(x-1)!(p-x)!}\bmod p=p*inv(x)*C_{p-1}^{x-1}\bmod p Cpxmodp=x!(p−x)!p!modp=xp∗(x−1)!(p−x)!(p−1)!