容斥
容斥
基本形态:
令 \(X\) 为所有 \(X_i\) 的集合,则可以简便地写成:
而在有些题目中,集合 \(X_{i_1}\cap X_{i_2}\cap X_{i_3}……X_{i_k}\) 的大小只依赖于 \(k\) 而不依赖具体的 \(X\),那么找到这些系数 \(a_0,a_1 \cdots a_n\) ,有公式:
煎蛋应用:错位排列
枚举有多少个位置不满足条件,那么有容斥:
P6076 [JSOI2015] 染色问题
有几种限制显然需要分开处理:
设 \(f_i\) 表示至多用 \(i\) 种颜色染棋盘的方案数。
那么如果没有前两个限制那么答案就是:
再考虑剩下两种限制,设 \(g_{i,j}\) 表示 \(i\) 种颜色至多 \(j\) 列有颜色的方案数。
对于每一行,保证至少有一个数,每行的方案数为 \((i+1)^j-1\),一共有 \(n\) 行,那么有:
再结合上面的式子即可。
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\) 的总和,那么有:
具体含义:
\(\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}\),即:
看似是 \(O(n^3)\) 的,但是循环次数仔细一算是:
其实是 \(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\) 里面的数的答案。
对于每个内层的树形 \(\text{dp}\) ,设 \(g_{x,i}\) 表示 \(x\) 的子树中 \(x\) 对应着节点 \(i\) 的方案数,\(vis_{x,y}\) 表示是否原图中 \(x\) 和 \(y\) 之间是否有连边。
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\) 最大的点,因为如果选择了不是最大的点,那么最大点就会被包含在矩形内部。
最后考虑包含某个矩形的所有正方形的总面积。
把 \(\min,\max\) 拆开,变成分段函数,分别求前缀和,细节依托,故从题单中删除。
P8329 [ZJOI2022] 树
介绍一种偷鸡的方法:你先写个暴力,打个表出来看看,第一棵树叶子集合为 \(S\) 的方案数和第二棵非叶子集合为 \(S\) 的方案数相等。感性理解下大概是两者大概是个对称关系,大概会存在一种对应方式。
代数证明非常困难,不多赘述,这里有证明。
那么我们现在只用考虑一棵树,设 \(f_S\) 表示第一棵树中非叶子节点恰好为 \(S\) 的方案数。
直接计算依旧困难,考虑容斥,设 \(g_S\) 表示非叶子节点为 \(S\) 的子集的方案数。
那么有:
答案为所有 \(f(S)\) 的平方和。
其实就可以做完了!具体而言,设 \(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\)
滚动数组一下,然后你就切掉了很牛很牛的 \(\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}\) 即表示区间本身是一个本源坏区间的方案数。
那么有:
\(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\)。
那么考虑稍微处理一下:
那么这样算的话,再算 \(f_{l,r}\) 的时候 \(g_{l,r,0}\) 内漏减了个 \(f’_{l,r}\) 刚好和外面的抵消了,最后再减回去即可。
复杂度 \(O(n^4)\),但区间 dp 自带小常数足以通过。
这样你就成功的用 \(\text{700b}\) 通过了一道 \(3500\) 的 CF题。