Examples

浅谈集合划分容斥

推荐阅读:2023 论文《对互异关系的容斥》by 周子衡。

本质是设计一种贡献系数,使得某种递推方法能得到正确的结果。

以前的理解不太深刻,今天仔细思考了一会儿。

一种形式化的描述:在某种等价关系下,对于某一组合结构,构成其的元素其可以被划分成若干等价类,有一关于等价类大小的系数 F(x)。而我们的 dp 不能恰好地刻画出每一极大等价类(有可能有相互等价的等价类),记等价类之间的合并关系为 G(x),我们设计容斥系数 H(x) 满足:

G(H(x))=F(x)

例如经典的 DAG 定向方案数的容斥系数为 (1)|S|+1,我们也能通过集合划分容斥得到同样的结果:

dp 的转移形式(每次添加一个子集)告诉我们合并关系为 Sequence 构造,即 G(S)=11S,而我们并不关心等价类大小,所以 F(S) 恒为 1

使用集合幂级数求逆得到 H(S)=(1)|S|+1,与 DAG 定向的容斥系数吻合(注意要求集合是独立集)。

ABC306H Balance Scale

本题若确定了 = 的边,我们将这些边缩起来做 DAG 计数就好了。因此我们枚举一个度数为 0 的子集,每个子集内的边都必须填 =,容斥系数就是这些边缩起来的连通块数量加一。

dp 的合并等价于集合幂级数求逆,复杂度 O(2nn2)

P7275 计树

可以将树划分成若干条值域连续的链,于是 F(x)=x21xG(x) 也是 Sequence 构造,即为 11x

注意要修正常数项,于是:

11H(x)1=x21x

得到 H(x)=x2x2x1。我们现在有若干条链需要合并成树,使用 prufer 序列,于是一条链的系数为容斥系数,乘上链的长度,再乘 m,使用 Sequence 构造在值域上进行合并即可。

复杂度 O(nlogn),可以观察到线性递推做到线性。

AGC058D Yet Another ABC String

要不是因为 unrated 做的有点拖沓,说不定咱就是这题一血了!

将序列划分成若干 ABCABCAB…… 连续段,于是关于连续段长度的贡献系数应是 1+x+x2,容斥系数容易计算:

H(x)=111+x+x2

当时直接写了个求逆看出了系数规律,不过也有文明一点的方法,写出线性递推,计算前几项后归纳。总之,我们得到了:

[xk]H(x)={0k=0 or k2(mod3)1k1(mod3)1k0(mod3)

于是一个连续段的生成函数为:

P(x)=(3i1aibici)+(i0aibici(a+b+c))

答案为:

[xn]11P(x)=1abc1abc+2abc

枚举下面选了几次 2abc 可以 O(1) 提取系数,复杂度 O(n)

loj#3395. 「2020-2021 集训队作业」Yet Another Permutation Problem

题意可以转化为存在至少一个长为 nk 的上升段,我们不妨计算最长连续段长度 <nk 的情况,记 m=nk,于是有:

11H(x)1=xxm1xH(x)=xxm1xm

于是一个长为 l 的段系数为:1l![xl]xxm1xm(还需分配具体数值)。

对于每个 m 都做一遍多项式求逆即可。由于模数不太好,我们暴力求逆做到 n2m,于是复杂度仍为 O(n2logn)

ARC140F ABS Permutation (Count ver.)

按照 +m 划分成很多条链,链长只有两种,我们尝试做 n 固定的情况,之后能使用多项式快速幂求出答案。

之后的步骤和前面几道题没有太大的差别,复杂度 O(nlog2n)

CF1553I Stairs

咕咕咕。

ABC236H Distinct Multiples

这一题要求“互不相同”,即所有等价类大小为 1,这种集合划分容斥又称斯特林容斥,我们要求:

expH(x)1=x

计算得 [xk]H(x)=(1)k1kk!=(1)k1(k1)!(注意是 EGF)。

于是本题的解法为:枚举一个集合,钦定其值相等(容易计算出方案数),乘上容斥系数做集合幂级数 exp,可以做到 O(2nn2)

7-11 翻硬币

给 zxy 咔头啦。

差分变成每次选择两个数同时取反,于是我们要求操作对应边互不相同,使用斯特林反演——我们尝试钦定一条边重复出现了 c 次,并附加 (1)c1(c1)! 的系数,而 (c1)! 的系数我们常常使用圆排列的组合意义进行转化。

具体的 dp 过程中,我们只需记录差分数组还有多少个位置是 1,转移考察编号最大的边,并实时维护一个环,要求其还没有收拢:

  • 在环内添加一个元素:枚举后继,产生剩余操作数量乘 1 的系数(注意此时我们同时考虑到了圆排列的系数);
  • 结束当前环:根据环长的奇偶性决定这条边造成的影响。

复杂度 O(nm)

事实上本题还有一种集合幂级数+单位根反演的做法,博主暂时不清楚这两种做法之间有何种联系。

ABC288H A Nameless Counting Problem

首先很容易通过数位 dp 计算出长度为 k 异或为 X 的序列个数,这一部分是 O(n3logV) 的。

一个不降序列可以通过删除若干相同 pair 映射到唯一的集合,于是我们若对于所有 k 计算出元素不同的,长度为 k 异或为 X 的序列个数,则可以通过塞入若干不影响异或和的相同 pair 来生成出所有不降序列,这无非是一个插板法。

元素互不相同指向了集合划分容斥,我们将出现次数为奇数的数与出现次数为偶数的数分开考虑,依次加入若干个“等价团”就可以 dp 出 i 个等价团,大小和为 j,大小全为奇数/偶数的容斥系数和。注意到我们并不在乎偶数大小的团的个数,只需将贡献乘上团个数阶乘的倒数来保证无序。

因此合并奇数偶数只用枚举奇数团的个数与大小和,以及偶数团的大小和,那么我们就可以 O(n3) 地计算上面那个问题了。

GDKOI2023 D1T3 异或图

m=0 时问题类似 P3447 [POI2006] KRY-Crystals。我们从高到低数位 dp,注意到性质——若某个数不卡上界,其余数可以任意选择,最后用这个数修正,于是可以得到 O(nlogV) 的做法。

我们使用集合划分容斥处理原问题,我们会划分出很多等价类,每个等价类都只在乎 a 的最小值。一个等价类的容斥系数可以通过对 [S] 这一集合幂级数求 ln 求得。

接下来我们直接写出 dp:fS,T 表示目前点集为 S,所有大小为奇数的连通块最小值可重集为 T 的系数之和,转移是枚举三个有包含限制的集合,复杂度为 O(4n),据说精细实现能做到 O(3n)

没写代码,式子不保证对。

P3214 [HNOI2011] 卡农

论文里有,咕咕咕。

loj#6728. U 群把妹王

我们若计算出 i 个行等价类的贡献系数 fii 个列等价类的贡献系数 gi,那么答案为:

ijfigjkij

使用 CZT 手法拆 ij=(i+j2)(i2)(j2) 就可以使用一次卷积解决,只需考虑如何求出 f,g

f 为例,通过集合划分容斥易得容斥系数为 H(x)=lnS,那么贡献系数为:

fi=[ti]exp(tlnS)

x 这一元使用扩展拉格朗日反演:

[xn]exp(tlnS)=1n[xn1](etx)(xQ(x))n

其中 Q(x)H(x) 的复合逆,而为了提取 t 的系数,我们需要知道 (xQ(x))n 各项系数,问题转为计算 Q(x),我们对 H(Q(x))x=0 进行牛顿迭代即可:

Q(x)=Q0(x)G(Q0(x))xG(Q0(x)x

上下均能暴力展开后复合,复杂度 O((a+b)nlogn)

ABC289H Trio

其实我也不清楚这算不算集合划分容斥,但其也是修正贡献的一种手法(我称其为“走回容斥”),因此也放上来了 。

注意到答案 F(x) 满足 F(x)H(x)=G(x),其中 [xt]H(x) 表示走 t 步,三个人均满足总位移为 0 的方案数,G(x) 表示走 t 步,三个人的位移恰好第一次符合条件的方案数。

注意到 G,H 不难计算,因为其对于某个 t,系数为:

i(ti)(ti+u)(ti+v)

可以使用一次卷积解决,复杂度 O(nlogn)

ARC124F Chance Meeting

若刻画两个人之间的距离,问题便被转化为:从 (0,0) 出发,共走 2n 步上步,m 步左步,m 步右步,求恰好经过一次 (0,n) 的方案数。

我们记 fi 为共使用 n 步上步,i 步左步,i 步右步,第一次到达 (0,n) 的方案数,到达 (0,n) 前后的路径是对称的,故答案为(记得钦定每个上步是谁贡献的):

(2nn)ififmi

于是我们使用上面的容斥方式,写出 H(x)=(2ii)xi=114x 以及 G(x) 表示向上走 n 步,左右各走 i 步,到达 (0,n) 的方案数,那么有:

F(x)H(x)=G(x)F(x)2=G2(x)H2(x)=(14x)G2(x)

提取一项系数容易做到线性。

随机游走3

不妨先考虑二维的情况,我们对某一位置,考察经过其的时间集合 S,使用容斥:

min(|S|,1)=TS(1)|T|+1

只需钦定一个时间集合,计算容斥系数之和。

假设到达该点的时间分别为 t0,t1,,tk,类似上面的走回容斥,我们分开考虑 [t0,tk] 的路径与其余路径。

前者即一条重返路径,先考虑一次重返对应的生成函数:

C(x)=k1(2kk)x2ki=0k(ki)2=k1(2kk)2x2k

而还需钦定重返次数并带上容斥系数,我们能写出:

1C+C2=11+C

后者仍是一条合法路径,问题即枚举一个点,再计算经过它的路径条数之和。反向枚举,先确定路径再确定点,若路径长为 m 方案数显然为 (m+1)4m

算完后者对应的生成函数除以 1+C 即可,复杂度 O(nlogn)

t 维情况是类似的,修改重返的生成函数为:

C(x)=k1(2kk)x2k[xk(k!)2](i0xi(i!)2)t

使用多项式快速幂解决即可,复杂度仍为 O(nlogn)

posted @   xiaoziyao  阅读(1210)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2022-07-07 2022-7-7 & 8 #8 AGC049E & AGC049D
点击右上角即可分享
微信分享提示