容斥原理 学习笔记

概念

1 定义

容斥原理也被称为逐步淘汰公式,是由于最终结果难以求解,通过不断地补充与排除(包容及排斥)得出最终答案的算法。

2 德摩根定律(De Morgan's Law)

有集合\(A\)\(B\),满足:

  1. \(\overline{A \cup B}=\overline{A} \cap \overline{B}\)

  2. \(\overline{A \cap B}=\overline{A} \cup \overline{B}\)

更一般的形式:

\[\overline{\bigcap\limits_{i \ge 1}A_i} =\bigcup\limits_{i \ge 1} \overline{A_i} \]

\[\overline{\bigcup\limits_{i \ge 1}A_i} =\bigcap\limits_{i \ge 1} \overline{A_i} \]

3 引例

\(U\) 是一个有限集合。 \(P_1,P_2,...,P_n\) 是与 \(U\) 中的元素相关的性质(对于 \(\forall x \in U , x\) 有且仅有其中 \(i(1 \leq i \leq n)\) 个性质),现在要求出 \(U\) 中具有所有性质的元素个数。

转化一下:

已知 \(U\)\(n\) 个子集 \(S_1,S_2,...,S_n\) ,求 \(| S_1 \cup ... \cup S_n|\)

\(|S_1\cup ...\cup S_n|\) 不易直接求解,但是对于 \(\forall k \in \N^+\)\(\{ 1,...,n\}\) 的任意非空子集 \(\{ i_1,...,i_k\}\) ,集合 \(|S_{i_1} \cap ... \cap S_{i_k}|\) 易于求解。

具体而言,我们有如下关于并集的 容斥原理的第一个公式

\[\left|\bigcup\limits_{i=1}^n S_i\right|=\sum\limits_{i=1}^n |S_i|-\sum\limits_{1 \leq i_1 < i_2 \leq n} |S_1 \cap S_2|+...+(-1)^{n-1} \cdot |S_1 \cap ...\cap S_n| \]

使用二项式定理证明每一个元素 \(x\) 出现的次数:

假设 \(x\) 出现在集合 \(T_1,T_2,...,T_k\) 中,则出现次数:

\[\begin{aligned} Cnt=&|\{T_i\}|-|\{T_i\cap T_j|i<j\}|+\cdots+(-1)^{k-1}\left|\left\{\bigcap_{i=1}^{k}T_{a_i}|a_i<a_{i+1}\right\}\right|\\ &+\cdots+(-1)^{m-1}|\{T_1\cap\cdots\cap T_m\}|\\ =&C_m^1-C_m^2+\cdots+(-1)^{m-1}C_m^m\\ =&C_m^0-\sum_{i=0}^m(-1)^iC_m^i\\ =&1-(1-1)^m=1 \end{aligned} \]

懒得写了所以直接照搬oi wiki

这个公式可以将题目从 满足任意一个约束 转化成 同时满足 \(k\) 个约束

对于交集的 容斥原理第二个公式 ,可以采用德摩根定理得出:

\[\left|\bigcap_{i=1}^{n}S_i\right|=|U|-\left|\bigcup_{i=1}^n\overline{S_i}\right| \]

这个公式可以将题目从 满足所有约束 转化成 同时不满足 \(k\) 个约束

注意:一般情况下容斥原理计算的结果很大,需要开long long

应用

一般对于有多个约束条件(属性),且要求满足所有 or 任意一个的数量(方案数)的问题,将符合约束条件的元素放入同一个集合,再进行容斥(当然,使用容斥原理也不应局限于集合,可以使用别的形式,具体而言要看题目)

在具体实现时,若 \(|S_i|\) 两两相等,对于相同的 \(p\) ,直接合并所有 \(|\bigcap\limits_{k=1}^p S_{i_k}|\) 的答案,将 \(p\)\(1\rightarrow n\) 扫一遍即可;若不相等,直接 \(2^n\) 暴力枚举,使用二进制(0/1表示元素在/不在,更简便)或DFS即可,若复杂度太高,优先考虑DFS+剪枝。

1. 全错排问题

求集合\(S=\{1,2,...,n\}\)的全错排个数\(D_n\)(全错位排列问题)。

\(S_i\)表示集合\(S\)中所有满足\(a_k=k\)的排列\((a_1,...,a_n)\)的集合,即\(k\)在其原先位置上。所求的便是 \(|\overline{S_{i_1}}\cap ... \cap \overline{S_{i_n}}|\)

事实上,\(|S_i|\) 两两相等,也就是说对于\(\forall k \in \N^+ ,k \leq n\),集合\(A=\{i_1,...,i_k\}\),集合\(B=\{j_1,...,j_k\}\),满足\(|S_{i_1} \cap ... \cap S_{i_k}|=|S_{j_1}\cap ... \cap S_{j_k}|\)

另容易得到 \(|S_{i_1} \cap ... \cap S_{i_k}|=(n-k)!\)(其中有\(k\)个数是固定的,剩下\(n-k\)个数可以任意排放)

也就是说 \(\sum\limits_{i_1<...<i_k}|S_{i_1}\cap ...\cap S_{i_k}|=\binom{n}{k}(n-k)!\)

则:

\[\begin{aligned} D_n &=|\overline{S_{i_1}}\cap ... \cap \overline{S_{i_n}}| \\ &=|U|-\sum\limits_{i=1}^n |S_i|+\sum\limits_{i_1<i_2}|S_{i_1}\cap S_{i_2}|-...+|S_{i_1}\cap ...\cap S_{i_n}| \\ &=n!-\sum\limits_{k=1}^n (-1)^k\cdot \binom{n}{k}(n-k)!\\ &=n!(1-\sum\limits_{k=1}^n (-1)^n\cdot \frac{1}{k!}) \end{aligned} \]

同时也可以使用递推的方式求解,设当前遍历到 \(a_i\) ,他可以放在 \([1,i-1]\) 的任意一个位置上,假设其为 \(j\),那么分两种情况: 位置 \(i\) 上的数为 \(a_j\) ,那么相当于剩下的 \(i-2\) 个数需要进行全错排,而 \(a_i\) 对应有 \(i-1\) 个合法位置,因此方案数为 \((i-1)\times D_{i-2}\) ; 若位置 \(i\) 上的数不为 \(a_j\) ,那么 \(a_j\) 一共有 \((i-1)\) 种方法,剩下的 \(i-1\) 个数进行全错排,共 \((i-1)\times D_{i-1}\) 种方案。因此有递推式:

\[D_i=(i-1)\times(D_{i-1}+D_{i-2}) \]

其中: \(D_1=0,D_2=1\)

这个方法明显会更简便。

2. 带限制不定方程非负整数解

对于不定方程: \(\sum\limits_{i=1}^n x_i=m\) ,有 \(n\) 个限制,第 \(i\) 个限制形如 \(x_i\leq b_i\) ,求非负整数 \(x_i\) 的解的组数。

若没有限制,则是经典的不定方程非负整数解,通过集体+1得出答案。

带上限制后,若用集合 \(S_i\) 表示满足约束 \(i\) 的解,那么题目所求便是: \(\left| \bigcap\limits_{i=1}^n S_i \right|\),运用补集思想,得:

\[\begin{aligned} \left| \bigcap\limits_{i=1}^n S_i \right| &=|U|-\sum\limits_{i=1}^n|\overline{S_i}|+\sum\limits_{i_1<i_2}|\overline{S_{i_1}}\cap \overline{S_{i_2}}|-...+(-1)^k\cdot\sum\limits_{i_1<i_2<...<i_k} \left|\bigcap\limits_{i_k} \overline{S_{i_k}}\right|+...+\left| \bigcap\limits_{i=1}^n \overline{S_i} \right| \end{aligned} \]

其中 \(\overline{S_i}\) 表示的便是满足 \(x_i\geq b_i+1\) 的解,对于任意的 \(|\overline{S_{i_1}}\cap...\cap \overline{S_{i_k}}|\) 而言,相当于满足 \(n\) 个变量中有 \(k\) 个满足上述的约束条件,即有下界限制,将其减去,就可以消除这个约束条件。即对于每一个 \(k\) 而言,将不定方程转化为:

\[\sum\limits_{i=1}^n x_i=m-\sum\limits_{i=1}^k (b_{A_i}+1) \]

其中 \(A_i\) 是一个 \(k\) 元集合,且 \(A_i=\{x|x\in \N_+,1\leq x\leq n\}\)

然后就转化为不定方程非负整数解的问题啦。

例题: [HAOI2008]硬币购物

3. 逆向运用

正向推导即将问题转化为左式,然后通过补集等技巧(也可能不需要),通过容斥原理展开进行求解,逆向推导即将问题转化为右式,然后通过容斥原理合并为左式,并通过补集等技巧再次展开为右式求解。

例题:(完全图染色问题)给定一个 \(n\) 阶完全图 \(G=(V,E)\),现给图上的点染色,共有 \(m\) 种颜色,规定有边直接相连的点必须染成同一种颜色,对于 \(G\) 的任意一个子图 \(G'=(V,S)\),定义函数 \(f(S)\) 表示边为集合 \(S\) 的染色方案数,若 \(|S|\) 奇数,则对答案有正贡献 \(f(S)\) ,否则有负贡献 \(-f(S)\) ,求最终贡献。

一开始想不到什么做法,可以先抽象为数学形式:

\[ans=\sum\limits_{S\subseteq E}(-1)^{|S|-1}f(S) \]

可以发现相邻点染同种颜色相当于一种约束,题目要求满足所有约束,不好直接求解,且式子中含有系数,考虑使用容斥。定义 \(Q_{i,j}\) 表示满足 \(i,j\) 染成同一种颜色的方案,则有:

\[f(S)=\left|\bigcap\limits_{(i,j)\in S}Q_{i,j}\right| \]

由于下表是二元组的集合很难进行容斥,可以进行一个映射,将边集 \(Q\) 映射为数集,即对于 \(1\leq k\leq n(n+1)/2\) ,定义 \(Q_{i,j}=Q_{(i-1)n+j}=Q_k\) ,对应地,我们要将边集 \(S\)\(E\) 都映射为数集, \(E\rightarrow E'=\{1,2,...,n(n+1)/2\}\)\(S\rightarrow S'=\{k_1,k_2,...,k_{|S|}\}\)

则有:

\[f(S')=\left| \bigcap\limits_{k_i\in S'}Q_{k_i} \right| \]

\[ans=\sum\limits_{S'\subseteq E'}(-1)^{|S'|}\left| \bigcap\limits_{k_i\in S'} Q_{k_i}\right| \]

这样就化成了容斥的形式(右式),有:

\[\begin{aligned} ans&=\left| \bigcup\limits_{i=1}^{n(n+1)/2} Q_{i} \right|\\ &=|U|-\left| \bigcap\limits_{i=1}^{n(n+1)/2} \overline{Q_i}\right| \end{aligned} \]

全集 \(|U|\) 即为任意染色的方案数 \(m^n\) ,而后半部分中满足所有有边直接相连的点异色,原图为完全图,因此即为所有点两两异色,方案数 \(A_{m}^n\) ,因此:

\[ans=m^n-A_{m}^n \]

然后就做完啦(ノ*・ω・)ノ

回顾一下步骤:找不到具体做法->抽象为数学公式->发现可以容斥->将原式向容斥公式靠拢(替换、映射)-> 容斥逆向推导得出答案

4. 数论中的应用

\(x,y\in \N_+,1\leq x,y\leq N\)\(f(k)\) 表示满足 \(\gcd(x,y)=k\) 的数对的数量,求 \(f(1)->f(N)\)

可以使用欧拉函数做,但是容斥原理也不差(●ˇ∀ˇ●)

可以知道:最大公约数为 \(k\) 的数对个数=公约数为 \(k\) 的数对个数-最大公约数为 \(k\) 的倍数的数对个数。可以列出转移方程:

\[f(k)=\lfloor N/k \rfloor ^2 -\sum\limits_{i=2}^{\lfloor N/k \rfloor} f(i\cdot k) \]

然后倒叙遍历即可,根据调和级数可知复杂度为 \(\Theta(\sum\limits_{i=1}^N N/i)=\Theta(N\sum\limits_{i=1}^N 1/i)=\Theta(N\log N)\)

例题:

[NOI2010]能量采集GCD Sum[SDOI2008]仪仗队

求欧拉函数 \(\varphi(n)\)

To be continued...

5. 另一种方式

对于两个函数 \(f(S)\)\(g(S)\)

若有:

\[f(S)=\sum\limits_{T\subseteq S}g(T) \]

则有:

\[g(S)=\sum\limits_{T\subseteq S}(-1)^{|S|-|T|}f(T) \]

这相当于容斥原理的第一个公式。另外有一个推论:

若有:

\[f(S)=\sum\limits_{S\in T} g(T) \]

则有:

\[g(S)=\sum\limits_{S\subseteq T} (-1)^{|T|-|S|} f(T) \]

这相当于容斥原理的补集形式。

posted @ 2020-11-25 13:11  lxzy  阅读(733)  评论(0)    收藏  举报