浅谈集合划分容斥
推荐阅读:2023 论文《对互异关系的容斥》by 周子衡。
本质是设计一种贡献系数,使得某种递推方法能得到正确的结果。
以前的理解不太深刻,今天仔细思考了一会儿。
一种形式化的描述:在某种等价关系下,对于某一组合结构,构成其的元素其可以被划分成若干等价类,有一关于等价类大小的系数 \(F(x)\)。而我们的 dp 不能恰好地刻画出每一极大等价类(有可能有相互等价的等价类),记等价类之间的合并关系为 \(G(x)\),我们设计容斥系数 \(H(x)\) 满足:
例如经典的 DAG 定向方案数的容斥系数为 \((-1)^{|S|+1}\),我们也能通过集合划分容斥得到同样的结果:
dp 的转移形式(每次添加一个子集)告诉我们合并关系为 Sequence 构造,即 \(G(S)=\frac 1{1-S}\),而我们并不关心等价类大小,所以 \(F(S)\) 恒为 \(1\)。
使用集合幂级数求逆得到 \(H(S)=(-1)^{|S|+1}\),与 DAG 定向的容斥系数吻合(注意要求集合是独立集)。
ABC306H Balance Scale
本题若确定了 =
的边,我们将这些边缩起来做 DAG 计数就好了。因此我们枚举一个度数为 \(0\) 的子集,每个子集内的边都必须填 =
,容斥系数就是这些边缩起来的连通块数量加一。
dp 的合并等价于集合幂级数求逆,复杂度 \(O(2^nn^2)\)。
P7275 计树
可以将树划分成若干条值域连续的链,于是 \(F(x)=\frac {x^2}{1-x}\),\(G(x)\) 也是 Sequence 构造,即为 \(\frac 1{1-x}\)。
注意要修正常数项,于是:
得到 \(H(x)=\frac{x^2}{x^2-x-1}\)。我们现在有若干条链需要合并成树,使用 prufer 序列,于是一条链的系数为容斥系数,乘上链的长度,再乘 \(m\),使用 Sequence 构造在值域上进行合并即可。
复杂度 \(O(n\log n)\),可以观察到线性递推做到线性。
AGC058D Yet Another ABC String
要不是因为 unrated 做的有点拖沓,说不定咱就是这题一血了!
将序列划分成若干 ABCABCAB…… 连续段,于是关于连续段长度的贡献系数应是 \(1+x+x^2\),容斥系数容易计算:
当时直接写了个求逆看出了系数规律,不过也有文明一点的方法,写出线性递推,计算前几项后归纳。总之,我们得到了:
于是一个连续段的生成函数为:
答案为:
枚举下面选了几次 \(-2abc\) 可以 \(O(1)\) 提取系数,复杂度 \(O(n)\)。
loj#3395. 「2020-2021 集训队作业」Yet Another Permutation Problem
题意可以转化为存在至少一个长为 \(n-k\) 的上升段,我们不妨计算最长连续段长度 \(<n-k\) 的情况,记 \(m=n-k\),于是有:
于是一个长为 \(l\) 的段系数为:\(\frac{1}{l!}[x^l]\frac{x-x^m}{1-x^m}\)(还需分配具体数值)。
对于每个 \(m\) 都做一遍多项式求逆即可。由于模数不太好,我们暴力求逆做到 \(\frac{n^2}{m}\),于是复杂度仍为 \(O(n^2\log n)\)。
ARC140F ABS Permutation (Count ver.)
按照 \(+m\) 划分成很多条链,链长只有两种,我们尝试做 \(n\) 固定的情况,之后能使用多项式快速幂求出答案。
之后的步骤和前面几道题没有太大的差别,复杂度 \(O(n\log^2 n)\)。
CF1553I Stairs
咕咕咕。
ABC236H Distinct Multiples
这一题要求“互不相同”,即所有等价类大小为 \(1\),这种集合划分容斥又称斯特林容斥,我们要求:
计算得 \([x^k]H(x)=\frac{(-1)^{k-1}}{k}k!=(-1)^{k-1}(k-1)!\)(注意是 EGF)。
于是本题的解法为:枚举一个集合,钦定其值相等(容易计算出方案数),乘上容斥系数做集合幂级数 exp,可以做到 \(O(2^nn^2)\)。
7-11 翻硬币
给 zxy 咔头啦。
差分变成每次选择两个数同时取反,于是我们要求操作对应边互不相同,使用斯特林反演——我们尝试钦定一条边重复出现了 \(c\) 次,并附加 \((-1)^{c-1}(c-1)!\) 的系数,而 \((c-1)!\) 的系数我们常常使用圆排列的组合意义进行转化。
具体的 dp 过程中,我们只需记录差分数组还有多少个位置是 \(1\),转移考察编号最大的边,并实时维护一个环,要求其还没有收拢:
- 在环内添加一个元素:枚举后继,产生剩余操作数量乘 \(-1\) 的系数(注意此时我们同时考虑到了圆排列的系数);
- 结束当前环:根据环长的奇偶性决定这条边造成的影响。
复杂度 \(O(nm)\)。
事实上本题还有一种集合幂级数+单位根反演的做法,博主暂时不清楚这两种做法之间有何种联系。
ABC288H A Nameless Counting Problem
首先很容易通过数位 dp 计算出长度为 \(k\) 异或为 \(X\) 的序列个数,这一部分是 \(O(n^3\log V)\) 的。
一个不降序列可以通过删除若干相同 pair 映射到唯一的集合,于是我们若对于所有 \(k\) 计算出元素不同的,长度为 \(k\) 异或为 \(X\) 的序列个数,则可以通过塞入若干不影响异或和的相同 pair 来生成出所有不降序列,这无非是一个插板法。
元素互不相同指向了集合划分容斥,我们将出现次数为奇数的数与出现次数为偶数的数分开考虑,依次加入若干个“等价团”就可以 dp 出 \(i\) 个等价团,大小和为 \(j\),大小全为奇数/偶数的容斥系数和。注意到我们并不在乎偶数大小的团的个数,只需将贡献乘上团个数阶乘的倒数来保证无序。
因此合并奇数偶数只用枚举奇数团的个数与大小和,以及偶数团的大小和,那么我们就可以 \(O(n^3)\) 地计算上面那个问题了。
GDKOI2023 D1T3 异或图
\(m=0\) 时问题类似 P3447 [POI2006] KRY-Crystals。我们从高到低数位 dp,注意到性质——若某个数不卡上界,其余数可以任意选择,最后用这个数修正,于是可以得到 \(O(n\log V)\) 的做法。
我们使用集合划分容斥处理原问题,我们会划分出很多等价类,每个等价类都只在乎 \(a\) 的最小值。一个等价类的容斥系数可以通过对 \([S 为独立集]\) 这一集合幂级数求 \(\ln\) 求得。
接下来我们直接写出 dp:\(f_{S,T}\) 表示目前点集为 \(S\),所有大小为奇数的连通块最小值可重集为 \(T\) 的系数之和,转移是枚举三个有包含限制的集合,复杂度为 \(O(4^n)\),据说精细实现能做到 \(O(3^n)\)。
没写代码,式子不保证对。
P3214 [HNOI2011] 卡农
论文里有,咕咕咕。
loj#6728. U 群把妹王
我们若计算出 \(i\) 个行等价类的贡献系数 \(f_i\),\(i\) 个列等价类的贡献系数 \(g_i\),那么答案为:
使用 CZT 手法拆 \(ij={i+j\choose 2}-{i\choose 2}-{j\choose 2}\) 就可以使用一次卷积解决,只需考虑如何求出 \(f,g\)。
以 \(f\) 为例,通过集合划分容斥易得容斥系数为 \(H(x)=\ln S\),那么贡献系数为:
对 \(x\) 这一元使用扩展拉格朗日反演:
其中 \(Q(x)\) 为 \(H(x)\) 的复合逆,而为了提取 \(t\) 的系数,我们需要知道 \((\frac{x}{Q(x)})^n\) 各项系数,问题转为计算 \(Q(x)\),我们对 \(H(Q(x))-x=0\) 进行牛顿迭代即可:
上下均能暴力展开后复合,复杂度 \(O((a+b)n\log n)\)。
ABC289H Trio
其实我也不清楚这算不算集合划分容斥,但其也是修正贡献的一种手法(我称其为“走回容斥”),因此也放上来了 。
注意到答案 \(F(x)\) 满足 \(F(x)H(x)=G(x)\),其中 \([x^t]H(x)\) 表示走 \(t\) 步,三个人均满足总位移为 \(0\) 的方案数,\(G(x)\) 表示走 \(t\) 步,三个人的位移恰好第一次符合条件的方案数。
注意到 \(G,H\) 不难计算,因为其对于某个 \(t\),系数为:
可以使用一次卷积解决,复杂度 \(O(n\log n)\)。
ARC124F Chance Meeting
若刻画两个人之间的距离,问题便被转化为:从 \((0,0)\) 出发,共走 \(2n\) 步上步,\(m\) 步左步,\(m\) 步右步,求恰好经过一次 \((0,n)\) 的方案数。
我们记 \(f_i\) 为共使用 \(n\) 步上步,\(i\) 步左步,\(i\) 步右步,第一次到达 \((0,n)\) 的方案数,到达 \((0,n)\) 前后的路径是对称的,故答案为(记得钦定每个上步是谁贡献的):
于是我们使用上面的容斥方式,写出 \(H(x)=\sum{2i\choose i}x^i=\frac 1{\sqrt{1-4x}}\) 以及 \(G(x)\) 表示向上走 \(n\) 步,左右各走 \(i\) 步,到达 \((0,n)\) 的方案数,那么有:
提取一项系数容易做到线性。
随机游走3
不妨先考虑二维的情况,我们对某一位置,考察经过其的时间集合 \(S\),使用容斥:
只需钦定一个时间集合,计算容斥系数之和。
假设到达该点的时间分别为 \(t_0,t_1,\cdots,t_k\),类似上面的走回容斥,我们分开考虑 \([t_0,t_k]\) 的路径与其余路径。
前者即一条重返路径,先考虑一次重返对应的生成函数:
而还需钦定重返次数并带上容斥系数,我们能写出:
后者仍是一条合法路径,问题即枚举一个点,再计算经过它的路径条数之和。反向枚举,先确定路径再确定点,若路径长为 \(m\) 方案数显然为 \((m+1)4^m\)。
算完后者对应的生成函数除以 \(1+C\) 即可,复杂度 \(O(n\log n)\)。
\(t\) 维情况是类似的,修改重返的生成函数为:
使用多项式快速幂解决即可,复杂度仍为 \(O(n\log n)\)。