容斥原理小记
梗概
如果一个限制不好做,那么我们可以使用容斥原理,以时间来降低问题的复杂性。
单步容斥
有 \(n\) 个集合 \(S_i\),求:
设 \(U\) 为全集,\(\overline{S_i}\) 为 \(S_i\) 对 \(U\) 的补集,单步容斥给出:
非常好理解。若一个元素 \(x\) 同时在所有的 \(S_i\) 中,那么它就不可能在任何一个 \(S_i\) 之外,反之亦然。
意义是,设 \(S_i\) 为满足性质 \(i\) 的元素集合,则第二条公式给出:
满足至少一个性质的元素个数等于所有元素个数减去满足零个性质的元素个数。
不知道从哪来的典题
称一个序列是好的,当且仅当存在一个数在序列中出现了两次及以上。
求所有长度为 \(n\),值域 \([1,m]\) 的序列中,好序列的个数。
用刚才的方式来理解,构造 \(m\) 个性质,性质 \(i\) 为序列中 \(i\) 元素出现了两次及以上,\(S_i\) 为所有满足性质 \(i\) 的序列(\(S_i\) 的元素是一个序列),则要求的是:
容易得知 \(|U|=m^n\),\(|\bigcap_{i=1}^n\overline{S_i}|=n!\binom{m}{n}\),所以答案显然。
P4692
拆分贡献,把贡献拆到每个颜色上。现在要统计对于一个颜色,有多少种方案包含了这个颜色至少一次。
考虑单步容斥,用所有方案数减去一次都不包含的方案数。后者显然可以 \(O(n)\) 计算。
带修,发现一次修改最多影响两种颜色的方案数,于是 STL set 维护一下每个颜色的位置做就行。\(O(q\log n)\)。
多步容斥
下面是最一般也是最基础的容斥原理,可以被称为是容斥原理的祖师爷。
有 \(n\) 个集合 \(S_i\),求:
容斥原理给出:
其将并集的大小转化为交集的大小。
看上去有点复杂。可以自己手画一个 \(n=2\) 的情形看一看,发现就是小学奥数容斥原理的拓展。
证明考虑每一个元素被算的次数。若一个元素被 \(k(k\geq 1)\) 个集合包含,则其被算的次数为:
得证。
这个公式也可以通过构造性质来运用。集合并集的意义是满足任意一条性质的元素集合,集合交集的意义是满足所有性质的元素集合。
P1450
转化题意:
求 \(x_1c_1+x_2c_2+x_3c_3+x_4c_4=s\) 的整数解个数,满足:
- \(x_1\leq d_1\)。
- \(x_2\leq d_2\)。
- \(x_3\leq d_3\)。
- \(x_4\leq d_4\)。
可以发现很自然地给出了四条限制,不妨设出来四个集合 \(S_1,S_2,S_3,S_4\) 分别表示满足上述四个限制的解 \((x_1,x_2,x_3,x_4)\) 的集合。
要求的是:
用一步单步容斥,再用多步容斥:
现在要算 \(|U|\) 和对于每个 \(T\subseteq [4],|T|=m\) 算 \(|\bigcap_{t\in T}\overline{S_t}|\)。
\(|U|\) 是好算的,就是未知数上界没有限制,下界为 \(0\),直接背包就行。
考虑 \(\bigcap_{t\in T}\overline{S_t}\) 的意义,是对于每个 \(t\in T\),都有 \(x_t>d_t\),也就是对这些未知数的取值设了一个下界,那么令 \(s\) 减去 \((d_t+1)c_t\),就变成了上界没有限制,下界为 \(0\) 的情况,就是背包。
于是时间复杂度 \(O(s+2^4)\)。
P3813
考虑一个矩形怎么做。发现 \(\max\leq k\) 的方案数很好算,那么要算 \(\max=k\),只需要用 \(\max\leq k\) 减去 \(\max<k\) 的方案数就行了。
多个矩形呢?先离散化,分成 \(O(n^2)\) 个块。发现限制会互相影响,于是现在要算 \(\forall 1\leq i\leq n,\max_i\leq k\) 减去 \(\exist 1\leq i\leq n,\max_i<k\) 的方案数。前者容易计算,后者是求集合并集的形式,于是直接上多步容斥即可。复杂度 \(O(2^nn^3)\)。
二项式反演
先解释一下反演的含义:
若有一个表达式能从 \(\{f_n\}\) 得到 \(\{g_n\}\) 的取值,那么从 \(\{f_n\}\) 反解出 \(\{g_n\}\) 的过程就叫反演。
对于二项式反演,表达式是:
反演式子是:
另外一种形式:
反演式子是:
证明略。
要解释其组合意义,还是考虑构造性质。
若有 \(n\) 个互相独立的形式相同的性质,设 \(f_i\) 为钦定满足 \(i\) 个性质的元素个数,\(g_i\) 为满足恰好 \(i\) 个性质的元素个数。
此处“钦定满足 \(i\) 个性质”的含义是,选出 \(i\) 个性质,令其必须满足。这从而导致一个满足 \(j\) 个性质的元素被统计 \(\binom{j}{i}\) 次。得到关系式:
若 \(f_i\) 容易计算,可以使用二项式反演解出满足恰好 \(i\) 个性质的元素个数。
对于另外一种形式,若有 \(n\) 个互相独立的形式相同的性质,设 \(f_i\) 为最多有 \(i\) 个性质满足的元素个数,\(g_i\) 为恰好 \(i\) 个性质满足的元素个数,有:
若 \(f_i\) 容易计算,可以使用二项式反演解出恰好 \(i\) 个性质满足的元素个数。
在这里,再次深入地探讨这两种二项式反演之间的不同之处,也就是“钦定”和“最多”的不同之处。
对于前者,如果设 \(h_i\) 为有 \(i\) 个性质随意满足的方案数,则有 \(f_i=\binom{n}{i}h_i\)。换句话说,需要先钦定出来钦定的性质到底是哪 \(i\) 个。因为关系式相当于“取一个大小为 \(i\) 的子集”,到底是哪 \(i\) 个性质与 \(f_i\) 确实有关。
对于后者,则不需要钦定满足的到底是哪 \(i\) 个。因为关系式相当于从 \(j\) 个性质添加一些不满足的性质来生成这 \(i\) 个性质,如果钦定了,则可能会出现不是子集的情况。
P6076
如果说一道题搞懂二项式反演,那么应该就是这道题了。
题目给出了四条限制,第一条限制其实是废话可以不看。重写一下剩下三条限制:
- 对于每个 \(1\leq i\leq n\),第 \(i\) 行必须存在至少一个格子被染色。
- 对于每个 \(1\leq i\leq m\),第 \(j\) 行必须存在至少一个格子被染色。
- 对于每个 \(1\leq i\leq c\),整个方格图必须存在至少一个颜色为 \(i\) 的格子。
可以发现其本质总共有 \(3\) 组限制,每组之内的限制没有本质不同。这意味着可以使用二项式反演。
先解决颜色这条限制。设 \(f_i\) 为最多出现 \(i\) 种颜色的方案数,\(g_i\) 为恰好出现 \(i\) 种颜色的方案数,于是有关系式:
反演得到:
答案即为 \(g_c\)。现在问题是怎么算 \(f_i\)。
发现还是很难算,所以再来解决行的限制。假如当前要求解 \(f_k\),也就是说有 \(k\) 种颜色可用。设 \(s_i\) 为钦定最多 \(i\) 行有颜色的方案数,\(t_i\) 为恰好 \(i\) 行有颜色的方案数,则有关系式:
反演得到:
要求的 \(f_k\) 即为 \(t_n\)。注意此时是先枚举 \(k\),再计算 \(s,t\),其值在不同的 \(k\) 下不同。现在要算 \(s_i\)。
最后解决列的限制。假如当前要求解 \(s_x\),也就是说有 \(k\) 种颜色,\(x\) 个行可用。设 \(p_i\) 为钦定最多 \(i\) 列有颜色的方案数,\(q_i\) 为恰好 \(i\) 列有颜色的方案数,则有关系式:
反演得到:
好现在所有限制都没有了,把总的答案式子整理一下:
其中 \(h(k,x,y)\) 表示 \(x\times y\) 的网格图,最多可以使用 \(k\) 种颜色,随便染色的方案数。显然为 \((k+1)^{xy}\)。
于是现在可以直接 \(O(nmc)\) 做了。当然先拿二项式定理化简一步再做可以 \(O(nc)\)。
P4491
套路地,设 \(f_i\) 表示钦定 \(i\) 种颜色出现恰好 \(S\) 次的方案数,\(g_i\) 表示恰好 \(i\) 种颜色出现恰好 \(S\) 次的方案数,则有:
反演得到:
现在要算 \(f_i\),容易写出:
含义为:从 \(m\) 种颜色钦定 \(i\) 个 \(\times\) 从 \(n\) 个位置选 \(iS\) 个填这 \(i\) 种颜色 \(\times\) 这 \(iS\) 个位置怎么填(多重集排列数)\(\times\) 剩下的自由选。
于是现在得到了 \(O(m^2)\) 做法,能不能更快?
观察一下模数,如果把它减去一分解一下质因数,发现有一堆 \(2\) 作为质因子,这说明可能会用到 NTT。二项式反演这个式子看着就很能卷积,化一下式子:
识别出差卷积形式,NTT 直接碾。复杂度 \(O(m\log m)\)。
P4448
首先把所有数除去平方因子,这样 \(a_i\times a_j\) 为完全平方数当且仅当 \(a_i=a_j\),这样就转化成了以下问题:
有 \(n\) 个有标号小球,每个小球有颜色,求有多少种排列方式满足同色小球不相邻。
暴力 DP 是 \(O(n^3)\) 的,能过但是有更快的容斥做法。
设 \(f_i\) 为钦定 \(i\) 对同色小球相邻的方案数,\(g_i\) 为恰好 \(i\) 对同色小球相邻的方案数,则有:
反演得到:
要求的是 \(g_0\),即:
考虑怎么求 \(f_i\),发现直接算不好搞,考虑 DP。
考虑按照颜色分类插入所有小球。设 \(dp_{i,j}\) 为插入了前 \(i\) 种颜色,有 \(j\) 个空位,若当前颜色小球有 \(s\) 个,钦定当前颜色相邻 \(k\) 对,则转移类似于背包:
DP 复杂度分析一下,是 \(O(n^2)\)。最终 \(f_i\) 即为 \(dp_{m,n-i+1}\)。
子集反演
见我的另外一篇博客。

浙公网安备 33010602011771号