【数学】组合数学

组合数学可以说是所有数论技巧中最有用的一种之一,无论是在生活中还是在学习中,都是一种极为方便的技能。

基本运算

加法原理

  若完成一件事的方法有 n n n 类,其中第 i i i 类方法有 a i a_i ai 种不同的实现方法,且这些方法互不重复,那么完成这些事共有 a 1 + a 2 + a 3 ⋯ + a n a_1 +a_2 +a_3\cdots+a_n a1+a2+a3+an 种不同的方法。这就是加法原理。

乘法原理

  若完成一件事需要 n n n 个步骤,其中第 i i i 个步骤有 a i a_i ai 种完成方法,且这些步骤互不干扰,则完成这件事共有 a 1 × a 2 × a 3 ⋯ × a n a_1\times a_2 \times a_3\cdots \times a_n a1×a2×a3×an种不同的方法,这就是乘法原理。

排列数

  从 n n n 个不同元素种依次取出 m m m 个元素排成一列,产生的不同排列的数量为: n × ( n − 1 ) × ⋯ × ( n − m + 1 ) = n ! ( n − m ) !      ( 乘 法 原 理 ) n \times(n - 1)\times\cdots \times(n - m +1) = \frac{n!}{(n - m)!}\ \ \ \ (乘法原理) n×(n1)××(nm+1)=(nm)!n!    () 写作 A n m A_n^m Anm P n m P_n^m Pnm

组合数

  从 n n n 个不同元素中取出 m m m 个构成一个集合,产生的不同集合数量为:
n × ( n − 1 ) × ( n − 2 ) × ⋯ ( n − m + 1 ) m × ( m − 1 ) × ( m − 2 ) × ⋯ × 2 × 1 ( 乘 法 原 理 ) = n ! m ! ( n − m ) ! \frac{n\times (n - 1)\times (n - 2)\times\cdots (n - m +1)}{m\times (m - 1)\times(m - 2)\times\cdots\times2\times1}(乘法原理)= \frac{n!}{m!(n - m)!} m×(m1)×(m2)××2×1n×(n1)×(n2)×(nm+1)()=m!(nm)!n!

性质

  1. C n m = C n n − m C_n^m = C_n^{n - m} Cnm=Cnnm
  根据组合数的定义,从 n n n 个元素中选出 m m m 个构成的集合一定和没有选的一 一对应。所以性质1成立。
  2. C n m = C n − 1 m + C n − 1 m − 1 C_n^m = C_{n - 1}^m +C_{n - 1}^{m - 1} Cnm=Cn1m+Cn1m1
  从 n n n 个元素中选出 m m m 个元素有两类方法:选择第 n n n 个和不选第 n n n 个。若选择第 n n n 个元素,那么就相当于在 n − 1 n - 1 n1 个数中选出 m − 1 m - 1 m1 个元素,方案数为 C n − 1 m − 1 C_{n - 1}^{m - 1} Cn1m1。若不选第 n n n 个元素,那么就相当于在 n − 1 n - 1 n1 个数中选出 m m m 个元素,方案数为 C n − 1 m C_{n - 1}^{m} Cn1m。所以方案数共有 C n − 1 m − 1 + C n − 1 m C_{n - 1}^{m - 1} + C_{n - 1}^{m} Cn1m1+Cn1m(加法原理)种情况。
  3. C n 0 + C n 1 + C n 2 + ⋯ + C n n = 2 n C_n^0 +C_n^1+C_n^2+\cdots+C_n^n = 2^n Cn0+Cn1+Cn2++Cnn=2n

求法

  1.我们可以直接用性质2来递推求解。复杂度为 O ( n 2 ) O(n^2) O(n2)。具体实现方法与杨辉三角相同。

  2.在实际运算中,组合数一般会很大,所以题目可能会要求对所求的组合数取模。在这种情况下,我们可以先求分子 n !   m o d   p n!\ mod\ p n! mod p ,再求分母 m ! ( n − m ) !   m o d   p m!(n - m)!\ mod\ p m!(nm)! mod p逆元,将其相乘之后就得到了所求的组合数。
  可以先将每一个 k ( k ∈ [ 0 , n ] ) k(k\in[0,n]) k(k[0,n]) k !   m o d   p k!\ mod\ p k! mod p及其逆元算出并存在两个数组中,这样在 O ( n ) O(n) O(n)的预处理之后就可以 O ( 1 ) O(1) O(1)地求组合数了。

  此外,当所求组合数为高精数时,我们可以先用阶乘分解1的方法。将分子分母快速分解质因数,在数组中保存各项质因数的次数,然后将分子和分母的质因子次数对应相减(消去分母),最后把剩余质因子乘起来,时间复杂度为 O ( n   l o g   n ) O(n\ log\ n) O(n log n)
  还有一种情况,那就是 n n n m m m 中有至少一个数比 p p p 要小。此时预处理求解就不那么适合了。对于该情况,我们可以使用 L u c a s Lucas Lucas 定理将一个 n n n m m m 较大的组合数分为若干个 n n n m m m 较小的组合数相乘进行求解


  1. 显然, n ! n! n! 中的每一个数都不会超过 n n n,所以我们可以先将小于 n n n 的质数 p p p 先全筛出来,在考虑在 n ! n! n! 有多少个质因子 p p p
       n ! n! n! p p p 的个数实际上就是 1 ~ n n n 中每个数包含质因子 p p p 的数量之和。显然,在1 ~ n n n 中, p p p 的倍数,即包含1个以上个 p p p 的数共有 ⌊ n p ⌋ \lfloor\frac{n}{p}\rfloor pn个, p 2 p^2 p2 的倍数,即包含2个以上 p p p 的数共有 ⌊ n p 2 ⌋ \lfloor\frac{n}{p^2}\rfloor p2n, p 3 p^3 p3 的倍数,即包含3个以上 p p p 的数共有 ⌊ n p 3 ⌋ \lfloor\frac{n}{p^3}\rfloor p3n…因为每一次提高 p p p 的个数时,之前的 p p p 已经计算过了,所以每次加上数的个数即可,而不是 p p p 的个数。
    综上所述, n ! n! n! 中包含 p p p 的个数为:
    ⌊ n p ⌋ + ⌊ n p 2 ⌋ + ⌊ n p 3 ⌋ + ⋯ ⌊ n p l o g p n ⌋ = ∑ p k ≤ n ⌊ n p k ⌋ \lfloor\frac{n}{p}\rfloor+\lfloor\frac{n}{p^2}\rfloor+\lfloor\frac{n}{p^3}\rfloor+\cdots\lfloor\frac{n}{p^{log_pn}}\rfloor =\sum_{p^k\leq n}\lfloor\frac{n}{p^k}\rfloor pn+p2n+p3n+plogpnn=pknpkn
      由此,对于每个 p p p,只需要 O ( l o g   n ) O(log\ n) O(log n)的时间就可以计算上述和式。因此对整个 n ! n! n! 进行质因子分解的时间复杂度为 O ( n   l o g   n ) O(n\ log\ n) O(n log n)↩︎

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值