组合计数

组合计数

与二项式有关的一些东西

组合数是啥相信大家都知道了就直接跳过了

众所周知,\((x+1)^2=x^2+2x+1\)\((x+1)^3\) 呢?可能有大佬秒切这个问题,即 \(x^3+3x^2+3x+1\),那 \((x+1)^n\) ? 在 \(n\) 比较小的时候可以暴力展开,但是 \(n\) 比较大了就不大行,于是我们就有了一个神奇的式子

\[(x+1)^n=\sum_{i=0}^n\binom{n}{i}x^i \]

更为普遍的,有

\[(x+y)^n=\sum_{i=0}^n\binom{n}{i}x^{i}y^{n-i} \]

怎么理解这个式子?OI不需要理解,背过就行

可以考虑 \((x+y)^n\) 的实际含义,是 \(n\)\((x+y)\) 乘起来,最终得到的一定是若干个 \(x^ay^b\) 相加的形式,所以可以考虑枚举 \(x\) 有多少个,从 \(n\) 中选出贡献 \(x\)\(a\)\((x+y)\) ,然后剩下的就贡献 \(y\) ,于是就有了上边的式子。

这个式子被称作 二项式定理

一般有啥用呢,可以展开若干个二项式相乘,得到某一项的系数,就不用 \(O(n)\) 算一遍了,或者可以把一个大的求和式子转化成一个快速幂。

组合数还有一些比较巧妙的东西,比如有两个函数 \(F,G\),满足

\[F_i=\sum_{j=i}^n\binom{j}{i}G_{j} \]

那么一定有

\[G_i=\sum_{j=i}^n\binom{j}{i}F_j(-1)^{j-i} \]

至于这个东西的证明,实际上很好证,只需要将上边的式子代入到下边的式子即可,不过这个东西感觉还是记住比较好,反正我是记的

实际上还有另一个形式

\[F_i=\sum_{j=0}^i\binom{i}{j}G_{j} \]

\[G_i=\sum_{j=0}^i\binom{i}{j}F_j(-1)^{i-j} \]

这两个式子被称作二项式反演

这个东西的用处非常大,因为一般计数的时候毒瘤出题人给出的恰好不太好算,但是至少是多少或者至多是多少就非常好整,举个例子

已经没有什么好害怕的了

题目大意

给定 \(n\)\(a_i\)\(n\)\(b_i\) ,要求将他们两两配对,使得 \(a_i > b_i\) 的组比 \(b_i>a_i\) 的组恰好多 \(k\) 个,保证给出的 \(a_i\)\(b_i\) 互不相同,即不可能存在 \(a_i=b_j\) 的情况 ,\(n\leq2000,k\leq n\)

恰好多 \(k\) 个这个限制就比较阴间,我们可以转化一下,随便解一个不等式可以得到两种情况的组数,并且可以发现,对于 \(n+k\) 是奇数的情况,答案一定为 \(0\),否则 \(a_i>b_i\) 的组数应该有 \(\frac{n+k}2\) 组。

\(t=\frac{n+k}2\) 那么问题转化为了,分成 \(n\) 组,\(a_i>b_i\) 的组数恰好有 \(t\) 组。

考虑直接 \(dp\) ,发现只能够状压,怎么看也过不去吧。。。

不过仔细分析一波发现,如果把 \(a_i\)\(b_i\) 分别排序然后对每一个 \(a_i\) 选择一个比它小的 \(b_i\) ,一共选 \(t\) 次,这个选择是比较好选的,因为排完序之后一个的选择会是另一个的子集,所以实际上并不关注选了谁,而关注选了多少个,这样是很好选择的,不过剩下的 \(n-t\) 组就不大好整了,因为我并不知道我选了哪些数,那咋办,剩下的随便组合就行。

不过很有可能会在剩下的 \(n-t\) 组中出现 \(a_i>b_i\) 的情况,这样就不是恰好 \(t\) 组了,即可能是恰好 \(t,t+1,t+2……n\) 组满足 \(a_i>b_i\)

也就是说大致我求了一个类似至少的东西,即至少是 \(t\) 组满足限制,不妨设 \(f_i\) 为至少有 \(i\) 组满足限制,\(g_i\) 为恰好有 \(i\) 组满足限制,直观上感觉有

\[f_i=\sum_{j=i}^ng_j \]

实际上并不是,考虑对于一个 \(g_j\) ,它真的只会被算一次吗?

对于一个 \(g_j\) ,会被算 \(\binom{j}{i}\) 次,因为对于每个算出来的恰好,其余组任意组合都能够得到这个方案,所以应该是

\[f_i=\sum_{j=i}^n\binom{j}{i}g_j \]

反演一下得到

\[g_i=\sum_{j=i}^n\binom{j}{i}f_j(-1)^{j-i} \]

然后就能直接做了,其中 \(f\) 数组可以简单 \(dp\) 得到 。

上面的题是至少的情况,定义至多的情况也是类似,就不再细说了,总之二项式反演最开始学可能不大会,但是仔细研究研究就会发现他真正的奥秘。

概率与期望?

不是组合计数吗怎么还有期望

实际上是一个和容斥有关的东西,叫 \(Min-Max\) 反演,通常用来解决概率的问题。

给出一个有点 \(nt\) 的问题,给一个全集,给出每个子集的最小值,求全集的最大值。

机智的大家一定会说,对所有值取一个 \(max\) 不就完了吗。

确实

但是出题人并没有这么 \(nt\) ,很多时候能够求出的最小值是一个期望,我们要求最大值的期望,期望只有在加减的时候才有线性性,所以并不能直接取 \(max\) ,我们需要一个能够直接加减得到最大值的式子。

具体的,有

\[\max(S) = \sum_{T \subseteq S \&\&T\neq\emptyset} (-1)^{|T|-1}\min(T) \]

最小值是同理的。

子集反演

其实就是一个式子,和二项式反演差不多,只不过限制条件由个数改成了具体是谁,设 \(F(S)\) 表示至多有 \(S\) 集合中的数满足要求,\(G(S)\) 表示恰好有 \(S\) 中的数满足要求,有

\[G(S) = \sum _{T \subseteq S}(-1)^{|S-T|}F(T) \]

一些特殊的数

伯努利数

问题1:

\(\sum_{i=0}^{n-1} 1\)

conitnue

问题2:

\(\sum_{i=0}^{n-1} i\)

等差数列求和

问题3:

\(\sum_{i=0}^{n-1} i^k,k\leq10^3,n\leq10^7\)

线性筛求和

问题4:

\(\sum_{i=0}^{n-1} i^k,k\leq10^3,n\leq10^9\)

不会了

实际上可以用拉格朗日插值插出来,不过这并不是重点,既然我们知道它是一个 \(k+1\) 次多项式,那么它的系数是不是有什么规律呢?

有一系列数 \(B_i\) ,首先有 \(B_0=1\),对于别的,有

\[\sum_{i=0}^k\binom{k+1}{i}B_i=0 \]

这就是伯努利数看起来没什么用

由上式可以看出可以 \(O(n^2)\) 预处理出伯努利数,然后呢?

再次扔出一个式子

\[\sum_{i=0}^{n-1} i^k=\frac{1}{k+1}\sum_{i=0}^k\binom{k+1}{i}B_in^{k+1-i} \]

然后就有了,具体应用还是要在题目中体会,不过遇到自然数幂和想想这个就行了。

斯特林数

第一类斯特林数

一般写作\({n \brack m}\),含义为将 \(n\) 个数划分为 \(m\) 个圆排列中的方案数。

圆排列是什么,其实也算排列,和排列的区别在于它循环同构,即 \(123,231,312\) 都是一种方案,显然 \(n\) 个数一个圆排列的方案为 \((n-1)!\),即一个排列 \(n\) 个数都能作为开头所以除去 \(n\)

那划分为 \(m\) 个呢?可以考虑递推,考虑第 \(n\) 个数放在哪,首先可以自己成为一个新的圆排列,其次可以插入到原来的圆排列中任意一个数的前边,即

\[{n \brack m}={n-1 \brack m-1}+(n-1){n-1 \brack m} \]

初始化\({0 \brack 0}=1\)这样就有了 \(O(n^2)\) 的写法,更快速的,可以做到 \(O(nlogn)\) 求一行或者一列的第一类斯特林数,不过这并不在本文的讨论范围内。

有一些比较有意思的性质,比如

\(n!=\sum_{i=0}^n{n \brack i}\)

因为一个置换可以看成若干个环,枚举所有的置换就相当与阶乘。

\(x^{\overline n}=\sum_{i=0}^n{n \brack i}x^i\)

这个实际上就是把若干个多项式乘起来就行,不再细说。

第二类斯特林数

一般写作 \({n \brace m}\),含义是将 \(n\) 个有区别小球放到 \(m\) 个无区别盒子中的方案数。

这个定义就比较清晰明了,注意有区别和无区别。

递推公式根据第一类的推法,考虑第 \(n\) 个小球放在哪儿,首先可以自己成为一组,也可以放到原来的任意一组中。

\[{n \brace m}={n-1 \brace m-1}+m{n-1 \brace m} \]

初始化\({0 \brace 0}=1\),可以 \(O(n^2)\) 递推,不过仍旧有快速求一行或是一列的办法,仍然不在讨论范围内。

这个也有很多有意思的性质,比如

\(m^n=\sum_{i=1}^m\binom{m}{i}{n \brace i}i!\)

这个是啥呢,\(m^n\) 可以理解成有 \(m\) 个有区别的盒子和 \(n\)个有区别的球,将球放到盒子里边,允许有空盒子的方案数。

那么我们可以枚举有几个盒子不是空的,然后用斯特林数把球放进去,不过注意盒子是有区别的所以要乘上一个阶乘。

找一道题练练手?

[省选联考 2020 A 卷] 组合数问题

题目大意

计算

\[\left(\sum_{k=0}^{n}f(k)\times x^k\times \binom{n}{k}\right)\bmod p \]

\(f(k)\) 为给定的一个 \(m\) 次多项式 \(f(k) = a_0 + a_1k + a_2k^2 + \cdots + a_mk^m\)

\(1\le n, x, p \le 10^9, 0\le a_i\le 10^9, 0\le m \le \min(n,1000)\)

首先显然我们拿这个多项式没有任何办法,不过考虑到它只有 \(m\) 次,所以直接展开,有

\[\begin{aligned} \sum_{k=0}^n\sum_{i=0}^ma_ik^ix^k\binom{n}{k}&=\sum_{k=0}^n \sum_{i=0}^m a_ix^k\binom{n}{k} \sum_{j=0}^i \binom{k}{j}j! {i \brace j}\\ &=\sum_{i=0}^m a_i \sum_{j=0}^i {i \brace j}j! \sum_{k=0}^n x^k \binom{n}{k}\binom{k}{j} \end{aligned} \]

注意到前边的时间复杂度已经对了,所以只需要把后边的时间复杂度整对就行。

有一个经典结论是

\[\binom{n}{k}\binom{k}{j}=\binom{n}{j}\binom{n-k}{k-j} \]

所以有,

\[\begin{aligned} \sum_{i=0}^m a_i \sum_{j=0}^i {i \brace j}j! \sum_{k=0}^n x^k \binom{n}{k}\binom{k}{j}&= \sum_{i=0}^m a_i \sum_{j=0}^i {i \brace j}j! \sum_{k=0}^n x^k \binom{n}{j}\binom{n-j}{k-j} \\ &=\sum_{i=0}^m a_i \sum_{j=0}^i {i \brace j}j!\binom{n}{j} \sum_{k=j}^n x^k \binom{n-j}{k-j}\\ &=\sum_{i=0}^m a_i \sum_{j=0}^i {i \brace j}\frac{n!}{(n-j)!} x^j\sum_{k=0}^{n-j} x^k \binom{n-j}{k} \\&= \sum_{i=0}^m a_i \sum_{j=0}^i {i \brace j}\frac{n!}{(n-j)!} x^j(x+1)^{n-j} \end{aligned} \]

然后这题就没了,实际上对于 \(n\) 比较大的情况一般都是用二项式定理转化成一个快速幂。

欧拉数

一般记作\(\langle\begin{smallmatrix}n\\ k\end{smallmatrix}\rangle\),表示对于一个排列中,有 \(k\) 个位置满足 \(a_i<a_{i+1}\)

考虑递推,最大的数不管插在哪里,除了放在开头外,一定会产生一个 \(a_i<a_{i+1}\),所以考虑放入最大的数会不会拆散之前的一对即可。

\[\left\langle\begin{matrix}n\\m\end{matrix}\right\rangle=(n-m) \left\langle\begin{matrix}n-1 \\ m-1 \end{matrix}\right\rangle+(m+1)\left\langle\begin{matrix}n-1\\m\end{matrix}\right\rangle \]

有一个性质是,

\[\left\langle\begin{matrix}n\\m\end{matrix}\right\rangle=\sum_{k=0}^{m}\binom{n+1}{k}(-1)^k(m+1-k)^n \]

具体证明我也不大会,记住就好。

有了这个性质后可以求一行的欧拉数,构造两个函数然后卷积即可。

三到六

题目大意

给定整数 \(n,k\) 和一个 \(n\) 阶排列 \(\pi'\),问多少个排列 \(\pi\) 满足恰有 \(k\) 个位置 \(i\) 满足 \(1 \le i \le n\)\(\pi_i < \pi_{\pi'_i}\)。答案对 \(998244353\) 取模。

数据范围

\(1 \le n \le 2 \times 10^5\)\(0 \le k \le n\)

由于排列是一个置换环的形式,不难发现题目要求在给出的排列中的置换环中,当前元素小于下一个元素的位置有 \(k\) 个,不同环之间是相对独立的,只需要对于每个环分别求答案然后最后分治 \(ntt\) 即可。

考虑对于一个大小为 \(n\) 的环,有 \(m\) 个位置满足要求的方案数是啥,如果这是一个序列,那么答案显然是欧拉数,不过由于这是一个环,就不大行了,考虑断环成链,从哪里断开呢?如果从 \(1\) 断开,那么由于 \(1\) 一定和后边的数形成一个 \(a_i<a_{i+1}\) ,所以实际上就是求一个长度为 \(n-1\) 的序列,有 \(k-1\) 个数满足 \(a_i<a_{i+1}\),这就是裸的欧拉数了,于是直接冲一个 \(ntt\) 然后就行了。

posted @ 2021-04-13 15:42  An_Fly  阅读(215)  评论(0编辑  收藏  举报