数学总结 5(简单容斥、二项式反演、子集反演、Min-Max 容斥初步)
一、简单容斥
错排问题
求有多少种长度为 \(n\) 的排列满足对于每一位 \(i\),有 \(p_i \not= i\)。
一种方法是线性递推:
显然有 \(f(1)=0,f(2)=1\),考虑 \(f(n)\) 如何求解。
对于 \(n-1\) 的错排,可以把其中每一个数分别和 \(n\) 位置交换,获得新的排列,即 \((n-1) f(n-1)\)。
也可以钦定某一位 \(p_i = i\),把 \(i\) 和 \(n\) 位置交换即可,而 \(i\) 有 \(n-1\) 种取值,所以方案数是 \((n-1) f(n-2)\)。
因此有:\(f(n) = (n-1)(f(n-1) + f(n-2))\)。
也可以从容斥的角度解决该问题:
考虑钦定一些点不满足条件,即 \(p_x = x\)。
先选出 \(i\) 个位置不满足条件,则方案数为 \(C_n^i\)。
剩下的位置可以随便排,所以方案数为 \(C_n^i (n-i)!\)。
然后容斥一下就是:
例 1:洛谷 P1450 HAOI2008 硬币购物
考虑容斥转化为好求的东西。
要容斥肯定要先有总数,这是好求的,是完全背包板子(即每个硬币不限使用量)。
然后枚举哪些硬币超出了范围,直接用 \(s\) 减掉 \((d+1)c\) 就是剩下的价值,也是不限量。
那么只要做一次完全背包就可以容斥算出答案。
例 2:CF1228E Another Filling the Grid
想了各种各样奇怪的做法,例如什么行列分开算之类的,枚举几行 \(\gt 1\) 求出行方案数,再另外枚举几列 \(\gt 1\) 在行的方案数基础上继续算。
但事实证明最直接的做法最简单。
由于 \(n\) 很小,可以直接枚举 \(i,j\) 表示至少有 \(i\) 行 \(j\) 列全 \(\gt 1\),那么就有 \(t= (i+j)n - ij\) 个格子必须 \(\gt 1\),方案数 \((k-1)^t\);其余的可以随便填方案数 \(k^{n^2-t}\)。
然后容斥一下就好了,系数为 \((-1)^{i+j}\)。
为什么会想到容斥?
如果直接钦定某一行最小值为 \(x\) 并不好做,但是可以钦定最小值 \(\geq x\),这样 \([x,k]\) 的数随便填,方案数可以直接算出来。
要还原回某一行最小值为 \(x\) 只需要做容斥就可以了,类似于莫反,也可以看作是一个后缀差求出单点值。
例 3:洛谷 P5505 JSOI2011 分特产
和之前相同地,刚好有 \(n\) 个同学至少拿到一个,改为前缀形式:\(f_i\) 表示有 \(\leq i\) 个同学获得至少一个。
如何求 \(f_i\)?先组合数确定有 \(C_n^i\) 种选法,然后对每个特产分别算贡献再乘法原理:相当于 \(a_j\) 个球扔进 \(i\) 个盒子,方案数 \(C_{i+a_j-1}^{i-1}\)。
容斥一下,答案显然是 \(ans = \sum\limits_{i=0}^n (-1)^{n-i} C_n^i \times \prod \limits_{j=1}^{m} C_{i+a_j-1}^{i-1}\)。
例 4:洛谷 P6076 JSOI2015 染色问题
容斥套容斥。
颜色看着很烦,先把它容斥掉变成好做的形式:设 \(dp_i\) 表示用 \(\leq i\) 种颜色填充的方案数,则答案为:
接下来这题不能像前面 CF1228E 一样枚举 \(i,j\) 分别考虑每个点,因为不能整行整列为空是一个整体,无法用零散的点完整表示信息。
所以老老实实一列一列容斥,和“恰好 \(c\) 种颜色一样”,恰好 \(m\) 列也可以变成 \(\leq m\) 列再容斥回来。
先选出 \(j\) 列:\(C_m^j\),然后对于每一行,只关注这 \(j\) 列的取值,它们不能全空,但可以从 \(i+1\) 种颜色(含空)之中任选,最后 \(n\) 行是独立的,所以方案数 \(((i+1)^j-1)^n\),因此:
……
但显然有一种更简单的方法。
三维枚举 \(i,j,k\) 表示几行全空,几列全空,只用多少种颜色,对于没有被选中的格子可以任意填剩下 \(c-k\) 种颜色或空,那么答案就是:
例 5:AGC005D ~K Perm Counting
错排问题的拓展,这一步数形结合还是太牛了。
由于和错排问题很相似,所以仍然考虑容斥,求出 \(\geq i\) 个不合法的位置有多少种方案。
然后数字与位置之间不能匹配(间隔为 \(k\))的条件很像二分图匹配,所以考虑用二分图辅助推导。
对于左部点(数字)向右部点(位置)相差恰好 \(k\) 的点连边,然后钦定它恰好有 \(i\) 条边被选择匹配,剩下的就乱排,方案数是阶乘,乘在一起就是 \(\geq i\) 个不合法的方案数。
注意到这个二分图有一些普通二分图没有的性质:点连成链,每条链是独立的。
那么对于每条链单独求方案数:设 \(dp_{i,j,0/1}\) 表示这条链计算到第 \(i\) 个点,匹配了 \(j\) 条边,第 \(i\) 个点是否被一条匹配边连上。
显然有:
转移就完了,如果对每条链分别做最后还要求一个背包,事实上可以把这些链首尾相连拼在一起,在链头特判不能转移到 \(dp_{i,j,1}\) 即可。
设 \(f_i=dp_{2n,i,0}+dp_{2n,i,1}\),表示恰好有 \(i\) 个位置不合法(选了 \(i\) 条边),则答案为:
例 6:\(\color{skyblue}{DTOJ ~ P2431 棋盘路径(path)}\)
题目大意:
有一个 \((n+1) \times (m+1)\) 的网格,求从 \((0,0)\) 走到 \((n,m)\) 的方案数(只能往右往下走)。
网格内有 \(k\) 个障碍物 \((x_1,y_1), (x_2,y_2), \dots, (x_k,y_k)\),在走的过程中不能触碰。
答案对 \(10^9+7\) 取模,\(n,m \leq 10^5, k \leq 3000\)。
不妨转化一下:求不经过其它障碍物到达第 \(i\) 个障碍物的方案数,设其为 \(f_i\)。
钦定 \((n,m)\) 是第 \(k+1\) 个障碍。则答案为 \(f_{k+1}\)。
到达一个障碍而不能经过其它障碍,考虑容斥,由于它只可能经过它左上方区域的障碍物,所以用这些障碍物作“中转站”,先到达其它障碍物再走到这个障碍物。
显然从 \((0,0)\) 走到 \((x,y)\) 无障碍的方案数为 \(\binom{x+y}{x}\)。
时间复杂度 \(O(k^2)\)。
二、二项式反演
类似于莫反。
设 \(f_i\) 表示恰好选了 \(i\) 个元素组合成满足条件形式的方案数;设 \(g_i\) 表示用 \(\leq n\) 个元素组合的方案数。
则二项式反演的常用形式为:
- 一般形式:
- 加下界:
- 上指标求和(常用于钦定至少有、恰好有,如错排问题):
例 7:CF285E Positions in Permutations
和 AGC005D 很相似。
要求恰好 \(m\) 个满足条件的位置,这不好做,还是转化为 \(\geq m\) 个之后再容斥。
首先钦定有 \(m\) 个满足条件,然后剩下的可以随便放。钦定部分还是 AGC005D 的 DP 部分方案数,剩下乱排方案数还是阶乘。
我们设 \(f_m\) 表示恰好 \(m\) 个,\(g_m\) 表示 \(\geq m\) 个。
于是有 \(g_m = \sum\limits_{i=m}^n \binom{i}{m} f_i\),根据上述推导还有 \(g_m = dp_{2n,i,0/1} \times (n-i)!\)。
那么 \(g\) 是容易求的,这个形式很二项式反演,所以 \(f_m = \sum\limits_{i=m}^n (-1)^{i-m} \binom{i}{m} g_i\)。
例 8:洛谷 P4859 已经没有什么好害怕的了
首先并不难推出需要恰好 \(\frac{n+k}{2}\) 个满足 \(a \gt b\) 的位置,以下设其为 \(m\)。
恰好不好做,改为钦定再做容斥。
设 \(g_i\) 表示有 \(\geq i\) 个位置满足条件,则先钦定有 \(i\) 个剩下乱排。
如何求出恰好有 \(i\) 个的方案数?由于 \(n \leq 2000\),考虑 \(O(n^2)\) 做法,例如 DP 计数。
设 \(dp_{i,j}\) 表示做到 \(a\) 的第 \(i\) 个(\(a,b\) 均已排序),有 \(j\) 个 \(a \gt b\) 的方案数,设 \(c_i\) 表示 \(b\) 中有多少个 \(\lt a_i\) 的数。
则不难推出转移式:
于是有 \(g_i = dp_{n,i} (n-i)!\)。
由于 \(g_m = \sum\limits_{i=m}^n \binom{i}{m} f_i\),不难反演得到 \(f_m\)。
三、子集反演
例 9:Bitwise And Convolution
求 And 卷积。
一眼 FWT 啊但是我 FWT 才学了一半。
那就上子集反演吧。
先转化为 \(g\) 的子集和形式,相当于要求 \(x,y\) 同时包含 \(z\) 就把 \(c_z\) 加上 \(a_x \times b_y\)。
即求出所有满足 \(x\) 包含 \(z\) 的 \(a_x\) 之和,\(b\) 同理,再相乘。
最后反演回 \(f\) 就是答案,复杂度 \(O(3^n)\)。
然后被卡了。
所以又回来补 FWT 了。跳转链接。
不过后来想了想貌似不需要 \(O(3^n)\)?类似于状压 DP 一位一位转移好像也可以做到 \(O(n 2^n)\)。
例 10:CF449D Jzzhu and Numbers
事实上,对于 \(\forall i\),都可以算出与和为 \(i\) 的方案数。
设 \(f_i\) 表示与和恰好为 \(i\) 的方案数,考虑子集反演,设 \(g_i\) 表示与和是 \(i\) 的超集的方案数。
既然是超集首先要知道 \(i\) 有多少个超集,设它为 \(c_i\),那么显然有 \(g_i = 2^{c_i} - 1\),因为不能选空。
显然 \(g_i,f_i\) 可以子集反演互推。
例 11:AT_tokiomarine2020_e O(rand)
简单题想了两个小时 /ll
看到这题有两个思路:
- 类似于之前某道题,把下界干成 \(0\) 变成单上界,接下来再搞一堆观察或许会有性质。
- 直接对二进制位容斥。
结果最后的做法成了两个的杂交版。
首先显然有 \(S \subseteq T\),为了简化问题,先进行如下转化:
- 依次考虑每一个二进制位,若 \(T=0,a=1\) 则这个 \(a\) 对答案没有贡献可以删掉,即 \(T ~|~ a \not= T\)。
- 若 \(S=1, a=0\) 也没有贡献,即 \(S \& a \not= S\)。
- 把确定无贡献的数全都踢出去之后,为了简化二进制形式,只把 \(T - S\) 二进制下为 \(1\) 的位保留,其它都删掉(类似于线性基重排二进制位)。
此时 \(T\) 全 \(1\),只需要选择一些 \(a\) 使得它们与和为 \(0\) 或和为全集即可。
正难则反,考虑一个二进制位如何才能不满足条件。
- 选出的所有数这一位都为 \(0\)。
- 选出的所有数这一位都为 \(1\)。
接下来对二进制位容斥,设 \(f_i\) 表示选择了 \(i\) 这个集合的二进制位,恰好只有这些位不满足条件的方案数。
一种转化是位置集合 \(i\) 的每一位都必须至少有一个 \(0\) 或 \(1\),但推了半天没什么进展。
然后转回来想想直接做就是对的:即对于 \(i\) 集合的每一位,选出的数在这一位都必须相同。
设选出的数是 \(a_1,a_2,\dots,a_k\),则 \(a_j \& i\) 相同的 \(a\) 才能同时被选择。
显然可以用一个桶维护 \(a_j \& i\) 的数字数量,然后组合数前缀和求一下选 \(1 \leq x \leq k\) 个数的方案数。
由于算出来的是 \(g_i\) 表示 \(i\) 的超集选择方案数,所以最后子集反演即可求出 \(f_0\)。
例 12:CF1530F Bingo
首先如果只有行的限制是好做的。
但题目添加了列和对角线,由于只有两条对角线,考虑简化问题,不管后面怎么做先把对角线 \(2^2\) 种方案容斥掉。
首先最暴力的做法是枚举选择的行列集合,它们全为 \(1\) 的概率是包含格子的概率乘积,剩下的格子随便取,设乘积为 \(val\) 则答案为 \(\sum\limits_{S} \sum\limits_{T} val(S,T)\)。
这样复杂度是 \(O(2^{2n})\),但容易发现只需要枚举 \(T\),对于 \(S\) 按行做容斥即可。
具体地,记 \(s0,s1\) 表示 \(|S|\) 分别为偶数、奇数的权值乘积之和,转移的时候考虑这一位选和不选的情况即可。
容易做到 \(O(2^n n^2)\),瓶颈在预处理,但是预处理也容易优化到 \(O(2^n n)\),注意求逆元不要套一个 \(\log V\),逆元也要预处理。
例 13:洛谷 P3349 ZJOI2016 小星星
不难写出朴素 DP:设 \(dp_{u,S,v}\) 表示树上 \(u\) 子树对应原图编号 \(S\) 集合,\(u\) 对应的编号是 \(v\) 的方案数。
这样枚举 \(u\) 和树上儿子,再枚举它们分别对应什么编号,还需要枚举对应集合,复杂度达到了高贵的 \(O(2^{2n}n^4)\)。
考虑优化,首先由于儿子的集合一定是 \(u\) 集合的子集,改为子集枚举可以优化到 \(O(3^n)\);其次并不需要枚举儿子对应的编号,可以邻居和搞一下变成 \(O(1)\) 查询,至此复杂度为 \(O(3^n n^3)\)。
枚举 \(u\) 和它的编号,再枚举儿子转移显然没有优化空间了,而主要瓶颈在于子集枚举。
能否通过“篡改”题目要求让 DP 状态更简单?
可以的,利用子集反演。
之前的算法为什么要枚举 \(S\)?因为图中的点不能算重,而子集反演转化后钦定它“可以算重”。
设树上点 \(u\) 的一个儿子是 \(v\),\(u\) 对应编号 \(a\),\(v\) 对应编号 \(b\),那只要满足图中 \(a,b\) 相邻即可。
设 \(f_S\) 表示树上的点恰好对应图中 \(S\) 集合的编号,则 \(f_{2^n-1}\) 就是答案;能算重意味着设 \(g_S = \sum\limits_{T \subseteq S}\),对于 \(g_S\) 的计算只要求 \(a,b \in S\)。
那么枚举 \(S\),树形 DP 求出 \(g_S\) 之后再子集反演求 \(f_{2^n-1}\)。具体地,设 \(dp_{u,a}\) 表示树上 \(u\) 子树,\(u\) 对应编号 \(a\) 的方案数。
复杂度降低为 \(O(2^n \times n^4)\),但跑不满,而且用邻居 dp 值之和优化可以降低为 \(O(2^n \times n^3)\)。
四、Min-Max 容斥(最值反演)初步
常用于 \(\max, \min\) 其一求解简单的时候用来求另一个。
简单证明一下第一个式子,至于第二个式子同理。
设 \(k\) 为 \(S\) 中最大的数。
右边的式子只有当 \(T= \{k\}\) 的时候才等于 \(k\)。
其它情况有 \(k\) 和没 \(k\) 的 \(\min\) 是相同的,所以加减抵消为 \(0\)。
还有扩展 Min-Max 容斥:
其中 \(\text{kmax}\) 表示集合中第 \(k\) 大的,\(\text{kmin}\) 同理。
Min-Max 容斥一般和期望、gcd 相关题结合,这里以期望举几个例子:
例 14:洛谷 P3175 HAOI2015 按位或
直接做看上去是一个很难的东西。
不妨先来想想弱化版:
有一个抽奖机,内置 \(n\) 种卡牌,每次抽奖编号为 \(i\) 的卡牌有 \(p_i\) 的概率被抽到,\(\sum\limits_{i=1}^{n} p_i = 1\),问抽到所有卡的期望次数。
抽到所有卡的期望次数相当于最晚被抽到的卡的时间。
但这个也非常难做……所以 Min-Max 容斥一下!
由于期望的线性性,有:
因此转化一下变成求解一个卡牌编号集合 \(T\) 的期望 \(\min\),即最早被抽到的卡期望抽到时间。
这个就简单了,先求概率:\(P(T) = \sum\limits_{i \in T} p_i\),就是抽一发抽到 \(T\) 集合内的概率。
那么不难推导出期望次数就是 \(\frac{1}{P(T)}\)。
于是就做完了,最后容斥回来就行,复杂度 \(O(2^n)\)。
回到本题,改变之处在于一次可以抽到多种卡牌,即一个集合 \(S\) 内的所有卡同时获得。
但还是一样地,只要 \(T\) 内有至少一个元素被抽到,那么它就满足条件。
所以现在要求 \(P(T)\) 表示所有和集合 \(T\) 有交的集合的概率之和。
这不好做。正难则反,求和 \(T\) 无交的集合的概率之和。
这依然不好做。正难则反,求为 \(T\) 的补集的子集的概率之和。
好了,这下就是高维前缀和板子了,复杂度 \(O(n 2^n)\)。
例 15:洛谷 P5643 PKUWC2018 随机游走
太喜欢这题了,一路推下来真的很顺……
首先看到所有点都经过至少一次,这很困难,所以 Min-Max 容斥转成经过集合内至少一个点的期望步数。
然后考虑这个怎么求,这不就是 概率与期望专题 的经典问题吗……
如果直接高斯消元,那总复杂度达到了高贵的 \(O(2^n n^3)\),但显然有 \(O(n)\) 做法。
不妨枚举 \(T\) 集合,设 \(f_i\) 为从 \(i\) 走到 \(T\) 集合内任意一点的期望步数,显然对于 \(i \in T\),有 \(f_i = 0\)。
于是 \(O(n)\) 就可以求解 \(f\) 数组。
接下来 min-max 容斥回去:
这是个简单的高维前缀和。
所以总复杂度 \(O(2^n n)\)。
例 16:洛谷 P4707 重返现世
由于 \(n-k\) 很小,做法大概率要基于这件事。
题目要求的是一个类似于 \(\text{kmin}\) 的东西,不妨先令 \(k \leftarrow n-k+1\),然后求 \(\text{kmax}\)。这两件事本质上是等价的,因为第 \(k\) 小的元素就是第 \(n-k+1\) 大的元素。
然后代入式子:
这也可以改写为期望形式。
对于一个集合的 \(\min\) 是好求的,显然为 \(\displaystyle \frac{m}{\sum\limits_{i \in T} p_i}\)。
难点在于如何求出所有满足条件 \(T\) 的和。
考虑一个个加入元素 \(i\),设 \(\sum p = j\),容斥的“下界”为 \(k\)(\(|T| \geq k\)),以此设计一个 DP 状态 \(dp_{i,j,k}\) 表示容斥系数之和。
这样的好处是对于同一个 \(j\),它的贡献 \(\min \{T\}\) 是已知的,所以只要 DP 求出容斥系数总和即可。
然后就是很妙的由状态反推转移方程。
由于 \(\binom{|T|-1}{k-1} = \binom{|T|-2}{k-2} + \binom{|T|-2}{k-1}\),
所以有:
这是选择元素 \(i\) 的转移,再加上不选择元素 \(i\),就是:
转移是 \(O(nm(n-k))\) 的,显然可以滚动数组优化空间。
初始化 \(dp_{0,0,0}=1\)。

浙公网安备 33010602011771号