容斥

容斥

基本形态:

\[\begin{aligned} |X_1\cup X_2 \cup X_3 \cup \cdots X_n|=\sum_{i}|X_i|-\sum_{i<j}|X_i \cap X_j| \cdots \\ +(-1)^{n-1}|X_1\cap X_2\cdots X_n| \end{aligned} \]

\(X\) 为所有 \(X_i\) 的集合,则可以简便地写成:

\[|\bigcup_{i=1}^{n}X_i|=\sum_{Y \subseteq X}(-1)^{|Y|-1}|\bigcap_{e\subseteq Y}e| \]

而在有些题目中,集合 \(X_{i_1}\cap X_{i_2}\cap X_{i_3}……X_{i_k}\) 的大小只依赖于 \(k\) 而不依赖具体的 \(X\),那么找到这些系数 \(a_0,a_1 \cdots a_n\) ,有公式:

\[\begin{aligned} |\overline{X_1}\cap \overline{X_2}\cap\cdots\overline{X_n}| =a_0-\binom{n}{1}a_1+\binom{n}{2}a_2+\cdots+ \\ (-1)^k\binom{n}{k}a_k+\cdots(-1)^n\binom{n}{n}a_n \end{aligned} \]

煎蛋应用:错位排列

枚举有多少个位置不满足条件,那么有容斥:

\[\sum_{i=0}^{n-1}(-1)^i\binom{n}{i}(n-i)!=n!(1-\dfrac{1}{1!}+\dfrac{1}{2!}-\dfrac{1}{3!}\cdots(-1)^n\dfrac{1}{n!}) \]

P6076 [JSOI2015] 染色问题

有几种限制显然需要分开处理:

\(f_i\) 表示至多用 \(i\) 种颜色染棋盘的方案数。

那么如果没有前两个限制那么答案就是:

\[f_c=\sum_{i=0}^{c-1}(-1)^i\binom{c}{i}f_{c-i} \]

再考虑剩下两种限制,设 \(g_{i,j}\) 表示 \(i\) 种颜色至多 \(j\) 列有颜色的方案数。

对于每一行,保证至少有一个数,每行的方案数为 \((i+1)^j-1\),一共有 \(n\) 行,那么有:

\[\begin{aligned} g_{i,j}&=((i+1)^j-1)^n \\ f_{i}&=\sum_{j=0}^{m-1}(-1)^{j}\binom{m}{j}g_{i,m-j} \end{aligned} \]

再结合上面的式子即可。

P2567 [SCOI2010] 幸运数字

这题其实比较平庸,主要是名字比较……

处理出所有只有 \(6\)\(8\) 的数,一共有 \(O(2^{10})\) 个数。

那么直接枚举子集复杂度是爆的,但是主要到几个数相乘很快贡献会变成 \(0\)

考虑几个很牛的剪枝:

1.如果一个幸运数字是另一个的倍数就把他删除,因为它没有贡献。

2.如果值大于了 \(R\) 就直接退出。

3.如果一个数大于了 \(\dfrac{R}{3}\),说明它不能和其他数组合相乘做贡献,预先统计答案。

然后足以通过。

P4448 [AHOI2018初中组] 球球的排列

首先注意到如果 \(x\)\(y\) 的乘积为平方数,\(y\)\(z\) 的乘积为平方数,那么 \(x\)\(z\) 的乘积也是平方数。那么一定可以将 \(n\) 若干个不交的等价类。

设可以划分出 \(m\) 个不交集合,第 \(i\) 个集合有 \(a_i\) 个元素,请计数有多少个排列满足排列中相邻两数不属于同一集合。

其实也就相当于求的是有恰好 \(0\) 个相邻点对属于一个集合。

这种恰好往往是困难的,转化为求至少有多少个相邻点对再容斥。

再设 \(b_i\) 表示第 \(i\) 个集合有至少 \(b_i\) 个相邻点对,再枚举 \(b_i\) 的总和,那么有:

\[ans=\prod_{i=1}^{m}a_i!\sum_{b_1+b_2+\cdots b_m=k}(-1)^k(n-k)!\prod_{i=1}^{m}\dfrac{1}{(a_i-b_i)!}\binom{a_i-1}{b_i} \]

具体含义:

\(\displaystyle\prod_{i=1}^{n}{a_i!}\):因为每个点的编号不同,所以答案要枚举全排列。

\((n-k)!\displaystyle\prod_{i=1}^{n}\dfrac{1}{(a_i-b_i)!}\):因为有 \(k\) 对相邻点对属于一个集合,也就相当于进行了一个绑定,那么还剩下 \((n-k)\) 个动点,对于第 \(i\) 个集合有 \(a_i-b_i\) 个动点,动点又不区分,那么也就有上式。

\(\displaystyle\prod_{i=1}^{n}\binom{a_i-1}{b_i}\):每个集合 \(a_i\) 个数要钦定至少 \(b_i\) 个数相邻,选择两个数间的空隙视为这两个数相邻,一共有 \(a_i-1\) 个空隙。

\(-1^k\) 就是正常的容斥系数。

写的时候就顺次枚举 \(i\) 以及 \(b_i\) 实时维护系数的变化即可。

具体而言,设 \(f_{i,j}\) 表示考虑前 \(i\) 个数中 \(\sum b_i\)\(j\)\(\displaystyle\prod_{w=1}^{i}\frac{1}{(a_w-b_w)!}\binom{a_w-1}{b_w}\) 的系数和。

每次转移的时候枚举 \(b_{i}\),即:

\[f_{i-1,j-b_i}\times \frac{1}{(a_i-b_i)!}\times \binom{a_i-1}{b_i}\to f_{i,j} \]

看似是 \(O(n^3)\) 的,但是循环次数仔细一算是:

\[\sum_{i=1}^{m}a_i\left(\sum_{j=1}^{i}a_i\right) \]

其实是 \(O(n^2)\) 的。

P3349 [ZJOI2016] 小星星

一种对子集状态的容斥。

首先有暴力:\(f_{i,j,S}\) 表示节点 \(i\) 对应着节点 \(j\),子树内部集合为 \(S\) 的方案数,转移的时候枚举每个儿子的所有状态进行类似卷积的操作。

复杂度 \(O(n^3\times 3^n)\),被爆了。

注意到复杂度主要来自于枚举子集。考虑能否将子集那一位的状态给删掉。

注意到子集那一位唯一需要刻画的是满足所有数两两不同的性质,或者说 \(1 \sim n\) 每个数恰好都出现了一次。

那么考虑将恰好一次转化为至多一次,再配合上容斥转移。枚举 \(1\sim n\) 的子集 \(S\) 表示钦定不在集合里面的数不能出现。设 \(f_S\) 表示只考虑集合 \(S\) 里面的数的答案。

\[ans=\sum_{S}(-1)^{n-|S|}f_S \]

对于每个内层的树形 \(\text{dp}\) ,设 \(g_{x,i}\) 表示 \(x\) 的子树中 \(x\) 对应着节点 \(i\) 的方案数,\(vis_{x,y}\) 表示是否原图中 \(x\)\(y\) 之间是否有连边。

\[\begin{aligned} g_{x,i}&=\prod_{y\in son_x}\sum_{j}vis_{i,j}f_{y,j} \\ f_{S}&=\sum_{i}g_{1,i} \end{aligned} \]

P9563 [SDCPC2023] Be Careful 2

暴力的枚举子集是 \(2^k\) 显然要被爆了。

首先注意到容斥的时候是枚举包含某个矩形的所有矩形的总面积。横纵坐标本质不同的个数只有至多 \(k\) 个,那么至多有 \(k^4\) 个小矩形,转化为枚举小矩形坐标再反推贡献。

然后再观察 \(k^4\) 个小矩形的容斥系数,注意到只有 \(k^2\) 个左右的小矩形容斥系数不为 \(0\) ,原因在于如果一个矩形内部包含了其他点,那么这个矩形一定是无贡献的,原因在于选内部的这个点和不选内部的这个点分别会带来 \(1\)\(-1\) 的贡献,刚好抵消。

所以只需要找出所有内部不包含其他点的矩形。

枚举左右边界的点 \((x1,y1),(x2,y2)\),那么下边界只能是 \(\min(y1,y2)\) 或者是 \(x\in(x1,x2),y\in(0,min(y1,y2))\) 的点中 \(y\) 最大的点,因为如果选择了不是最大的点,那么最大点就会被包含在矩形内部。

最后考虑包含某个矩形的所有正方形的总面积。

\[\begin{aligned} ans&=\sum_d{d^2}w_x(d)w_y(d) \\ w_x(d)&=\max(0,\min(x_1-1,n-d)-\max(0,x_2-d-1)+1) \\ w_y(d)&=\max(0,\min(y_1-1,m-d)-\max(0,y_2-d-1)+1) \end{aligned} \]

\(\min,\max\) 拆开,变成分段函数,分别求前缀和,细节依托,故从题单中删除。

P8329 [ZJOI2022] 树

介绍一种偷鸡的方法:你先写个暴力,打个表出来看看,第一棵树叶子集合为 \(S\) 的方案数和第二棵非叶子集合为 \(S\) 的方案数相等。感性理解下大概是两者大概是个对称关系,大概会存在一种对应方式。

代数证明非常困难,不多赘述,这里有证明

那么我们现在只用考虑一棵树,设 \(f_S\) 表示第一棵树中非叶子节点恰好为 \(S\) 的方案数。

直接计算依旧困难,考虑容斥,设 \(g_S\) 表示非叶子节点为 \(S\) 的子集的方案数。

那么有:

\[\begin{aligned} g(S)&=\prod_{i=2}^{n}\sum_{j\in S}[j<i] \\ f(S)&=\sum_{T\subset S}(-1)^{|T|}g(S\backslash T) \end{aligned} \]

答案为所有 \(f(S)\) 的平方和。

\[\begin{aligned} \sum_Sf^2(S)&=\sum_S\left(\sum_{T_1\subset S}(-1)^{|T_1|}g(S\backslash T_1)\right)\left(\sum_{T_2\subset S}(-1)^{|T_2|}g(S\backslash T_2)\right)\\ &=\sum_S\sum_{T_1\subset S}\sum_{T_2\subset S}(-1)^{|T_1|+|T_2|}\left(\prod_{i=2}^{n}\sum_{j\in S\backslash T_1}[j<i]\right)\left(\prod_{i=2}^{n}\sum_{j\in S\backslash T_2}[j<i]\right)\\ &=\sum_S\sum_{T_1\subset S}\sum_{T_2\subset S}(-1)^{|T_1|+|T_2|}\prod_{i=2}^{n}\left(\sum_{j\in S\backslash T_1}[j<i] \right)\left(\sum_{j\subset S\backslash T_2}[j<i]\right) \end{aligned} \]

其实就可以做完了!具体而言,设 \(f_{i,j,k}\) 表示前 \(i\) 个点只考虑 \(|S\backslash T_1|,|S\backslash T_2|\) 的大小分别为 \(j,k\),考虑 \(f_{i,j,k}\) 能转移到哪里。

一共分五种情况,设 \(x=f_{i,j,k}\times j\times k\)

\[\begin{cases} +x\to f_{i+1,j,k} & S 不选\\ +x\to f_{i+1,j+1,k+1} & S选,T_1 不选,T_2 不选\\ -x\to f_{i+1,j+1,k} & S选,T_1 选,T_2 不选\\ -x\to f_{i+1,j,k+1} & S选,T_1 不选,T_2 选\\ +x\to f_{i+1,j,k} & S选,T_1选,T_2选 \end{cases} \]

滚动数组一下,然后你就切掉了很牛很牛的 \(\text{ZJOI2022}\) 的一道题

Jellyfish and OEIS

容斥好题。

如果 \([l,r]\) 不满足条件,那么称 \([l,r]\) 为坏区间。

首先有一个观察到如果 \([l1,r1],[l2,r2]\) 都是坏区间,且 \(l1\le l2 \le r1\le r2\),那么 \([l1,r2],[l2,r1]\) 也是坏区间。

再称本源坏区间为不包含其他的不满足其他条件的区间。

考虑使用区间 dp 去刻画状态,这 \(f_{l,r}\) 表示区间 \([l,r]\) 区间由 \([l,r]\) 构成且不严格包含任何不满足条件的区间。那么有如果 \(a_1=n\) 则无解,否则为 \(f_{1,n}\)

考虑可以容斥计算 \(f_{l,r}\),设 \(g_{0/1,l,r,x}\) 表示区间内钦定了包含奇数/偶数个本源坏区间,留下的空位总数为 \(x\) 的方案数,再设 \(g_{l,r,x}=g_{0,l,r,x}-g_{1,l,r,x}\)。设 \(f’_{l,r}=[a_l\le r]f_{l,r}\) 即表示区间本身是一个本源坏区间的方案数。

那么有:

\[\begin{aligned} f_{l,r}&=\sum_{i=0}^{r-l+1}g_{l,r,x}x!+f'_{l,r} \\ g_{l,r,x}&=g_{l,r-1,x-1}-\sum_{k=l}^{r}g_{l,k-1,x}f'_{k,r} \end{aligned} \]

\(g\) 的计算即看最后一个位置为空或者枚举最后一个本源坏区间。

\(f\) 的时候要加上 \(f’_{l,r}\) 的原因是 \(f\) 算的是严格包含,而只有钦定了区间 \([l,r]\) 为本源坏区间被算进了 \(g_{1,l,r,0}\) 内,要加会贡献。

注意到 \(f_{l,r}\) 可能转移到自己,即计算 \(g\) 的时候 \(k\) 取到了 \(l\)

但又注意到 \(g_{k,k-1,x}\) 只有在 \(x=0\) 的时候值为 \(1\)

那么考虑稍微处理一下:

\[\begin{aligned} g_{l,r,x}&=g_{l,r,x-1}-\sum_{k=l}^{r-1}g_{l,k,x}f'_{k+1,r} \\ f_{l,r}&=\sum_{x=0}^{r-l+1}g_{l,r,x}x! \\ g_{l,r,0}&=g_{l,r,0}-f’_{l,r} \end{aligned} \]

那么这样算的话,再算 \(f_{l,r}\) 的时候 \(g_{l,r,0}\) 内漏减了个 \(f’_{l,r}\) 刚好和外面的抵消了,最后再减回去即可。

复杂度 \(O(n^4)\),但区间 dp 自带小常数足以通过。

这样你就成功的用 \(\text{700b}\) 通过了一道 \(3500\) 的 CF题。

posted @ 2024-04-26 08:45  Hanghang007  阅读(51)  评论(2编辑  收藏  举报