组合计数
组合计数
与二项式有关的一些东西
组合数是啥相信大家都知道了就直接跳过了
众所周知,\((x+1)^2=x^2+2x+1\), \((x+1)^3\) 呢?可能有大佬秒切这个问题,即 \(x^3+3x^2+3x+1\),那 \((x+1)^n\) ? 在 \(n\) 比较小的时候可以暴力展开,但是 \(n\) 比较大了就不大行,于是我们就有了一个神奇的式子
更为普遍的,有
怎么理解这个式子?OI不需要理解,背过就行
可以考虑 \((x+y)^n\) 的实际含义,是 \(n\) 个 \((x+y)\) 乘起来,最终得到的一定是若干个 \(x^ay^b\) 相加的形式,所以可以考虑枚举 \(x\) 有多少个,从 \(n\) 中选出贡献 \(x\) 的 \(a\) 个 \((x+y)\) ,然后剩下的就贡献 \(y\) ,于是就有了上边的式子。
这个式子被称作 二项式定理 。
一般有啥用呢,可以展开若干个二项式相乘,得到某一项的系数,就不用 \(O(n)\) 算一遍了,或者可以把一个大的求和式子转化成一个快速幂。
组合数还有一些比较巧妙的东西,比如有两个函数 \(F,G\),满足
那么一定有
至于这个东西的证明,实际上很好证,只需要将上边的式子代入到下边的式子即可,不过这个东西感觉还是记住比较好,反正我是记的
实际上还有另一个形式
这两个式子被称作二项式反演。
这个东西的用处非常大,因为一般计数的时候毒瘤出题人给出的恰好不太好算,但是至少是多少或者至多是多少就非常好整,举个例子
题目大意
给定 \(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\) 组满足限制,直观上感觉有
实际上并不是,考虑对于一个 \(g_j\) ,它真的只会被算一次吗?
对于一个 \(g_j\) ,会被算 \(\binom{j}{i}\) 次,因为对于每个算出来的恰好,其余组任意组合都能够得到这个方案,所以应该是
反演一下得到
然后就能直接做了,其中 \(f\) 数组可以简单 \(dp\) 得到 。
上面的题是至少的情况,定义至多的情况也是类似,就不再细说了,总之二项式反演最开始学可能不大会,但是仔细研究研究就会发现他真正的奥秘。
概率与期望?
不是组合计数吗怎么还有期望
实际上是一个和容斥有关的东西,叫 \(Min-Max\) 反演,通常用来解决概率的问题。
给出一个有点 \(nt\) 的问题,给一个全集,给出每个子集的最小值,求全集的最大值。
机智的大家一定会说,对所有值取一个 \(max\) 不就完了吗。
确实
但是出题人并没有这么 \(nt\) ,很多时候能够求出的最小值是一个期望,我们要求最大值的期望,期望只有在加减的时候才有线性性,所以并不能直接取 \(max\) ,我们需要一个能够直接加减得到最大值的式子。
具体的,有
最小值是同理的。
子集反演
其实就是一个式子,和二项式反演差不多,只不过限制条件由个数改成了具体是谁,设 \(F(S)\) 表示至多有 \(S\) 集合中的数满足要求,\(G(S)\) 表示恰好有 \(S\) 中的数满足要求,有
一些特殊的数
伯努利数
问题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\),对于别的,有
这就是伯努利数,看起来没什么用。
由上式可以看出可以 \(O(n^2)\) 预处理出伯努利数,然后呢?
再次扔出一个式子
然后就有了,具体应用还是要在题目中体会,不过遇到自然数幂和想想这个就行了。
斯特林数
第一类斯特林数
一般写作\({n \brack m}\),含义为将 \(n\) 个数划分为 \(m\) 个圆排列中的方案数。
圆排列是什么,其实也算排列,和排列的区别在于它循环同构,即 \(123,231,312\) 都是一种方案,显然 \(n\) 个数一个圆排列的方案为 \((n-1)!\),即一个排列 \(n\) 个数都能作为开头所以除去 \(n\) 。
那划分为 \(m\) 个呢?可以考虑递推,考虑第 \(n\) 个数放在哪,首先可以自己成为一个新的圆排列,其次可以插入到原来的圆排列中任意一个数的前边,即
初始化\({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\) 个小球放在哪儿,首先可以自己成为一组,也可以放到原来的任意一组中。
初始化\({0 \brace 0}=1\),可以 \(O(n^2)\) 递推,不过仍旧有快速求一行或是一列的办法,仍然不在讨论范围内。
这个也有很多有意思的性质,比如
\(m^n=\sum_{i=1}^m\binom{m}{i}{n \brace i}i!\)
这个是啥呢,\(m^n\) 可以理解成有 \(m\) 个有区别的盒子和 \(n\)个有区别的球,将球放到盒子里边,允许有空盒子的方案数。
那么我们可以枚举有几个盒子不是空的,然后用斯特林数把球放进去,不过注意盒子是有区别的所以要乘上一个阶乘。
找一道题练练手?
题目大意
计算
\(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\) 次,所以直接展开,有
注意到前边的时间复杂度已经对了,所以只需要把后边的时间复杂度整对就行。
有一个经典结论是
所以有,
然后这题就没了,实际上对于 \(n\) 比较大的情况一般都是用二项式定理转化成一个快速幂。
欧拉数
一般记作\(\langle\begin{smallmatrix}n\\ k\end{smallmatrix}\rangle\),表示对于一个排列中,有 \(k\) 个位置满足 \(a_i<a_{i+1}\)
考虑递推,最大的数不管插在哪里,除了放在开头外,一定会产生一个 \(a_i<a_{i+1}\),所以考虑放入最大的数会不会拆散之前的一对即可。
有一个性质是,
具体证明我也不大会,记住就好。
有了这个性质后可以求一行的欧拉数,构造两个函数然后卷积即可。
题目大意
给定整数 \(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\) 然后就行了。