在有些时候,当我们无法很好的刻画出一个极大物时(一个极大物可能会被划分成若干非极大物),我们也需要求出一个容斥系数 H(x),使得对于所有对极大物的划分方法,每个非极大物的容斥系数的乘积之和,恰好为我们所需要的系数 F(x)。设 G(x) 为拼接函数,则有 G(H(x))=F(x),比如说 G(x) 在拼接有序的时候一般是 1−x1,无序的时候一般是 exp。
例子:DAG 定向方案数
套路的考虑每次删掉一个独立集来 dp,但是这样会使得本可以一次删掉的独立集被分多次删掉而导致记重。于是我们考虑乘上容斥系数 hi,使得 fi=∑j=0i(ji)fi−jhj,即 i!fi=∑j=0i(i−j)!fi−jj!hj。因为独立集大小无论多少,我们都希望计算 1 的系数,所以 ∀i,fi=1。设 F(x)=i!xifi,H(x)=i!xihi,则有 1−H(x)1=F(x)。
写个求逆就可以发现 hi 的规律为 hi=(−1)i−1,归纳证明也是简单的。
我们考虑将一个字符串划分成若干极长的形如 ABCABCABCABCAB...
的段,比如 BCBABBCCABCAB
会被划分成这样:BC|B|AB|BC|CABCAB
。那么我们对于一个合法串的要求就是,每一段的长度都 ≤2。
但是极长连续段是不太方便刻画的,而如果不考虑极长的限制,一个极长段可能在实际计算方案时被划分成若干子段。所以我们考虑设计一个只和长度有关的容斥系数 hi,使得一个极长段的所有划分方案的容斥系数的乘积和为所需的系数 fi,则 fi=∑j=0ifi−jhj。
写成生成函数的形式(即 [xi]H(x)=hi,[xi]F(x)=fi),也就是 1−H(x)1=F(x)。
而我们希望极长段的长度 ≤2,所以长度 >2 的极长段我们想让其系数为 0,否则我们希望其系数为 1。所以在这里,F(x)=1+x+x2,我们想要倒过来推出 H(x)。
1−H(x)1=1+x+x2H(x)=x+x2−(x+x2)H(x)
然后就可以写出线性递推形式 h1=1,h2=0,hi=−hi−1−hi−2(i≥3)。归纳一下可以得到规律:
hi=⎩⎪⎨⎪⎧10−1i≡1(mod3)i≡2(mod3)i≡0(mod3)
当然也可以直接写个求逆然后找规律。于是我们对长度 mod3=1 和长度 mod3=0 的两种段分别考虑(系数为 0 的不需考虑),得到一个连续段的生成函数:
P(a,b,c)=(a+b+c)i≥0∑aibici−3i≥1∑aibici=1−abca+b+c−3abc
答案即为连续段任意拼接起来的生成函数:
[aAbBcC]1−P(a,b,c)1=[aAbBcC]1+2abc−a−b−c1−abc
设 Q(a,b,c)=1+2abc−a−b−c1,则答案为:
[aAbBcC]Q(a,b,c)−[aA−1bB−1cC−1]Q(a,b,c)Q(a,b,c)=1+2abc−a−b−c1=1−(a+b+c−2abc)1=i≥0∑(a+b+c−2abc)i
枚举选择了多少个 −2abc 即可 O(A+B+C) 计算答案。
首先最终的排列中间没动的一段一定是一个极长上升连续段,设其长度为 l,则至少要操作 n−l 次。我们对于一个排列,为了最小化操作次数显然要保留最长的一段。所以一个排列能被 k 次操作得到,至少要有一段长度 ≥n−k 的上升连续段。容斥一下计算无法得到的,就是每个极长上升连续段长度都是 <n−k 的。
这一题中我们也无法较好地刻画出极长上升连续段,所以类似于上一题,我们所需的系数为 F(x)=1−xx−xn−k,类似的推导可以得出规律:
hi=⎩⎪⎨⎪⎧10−1i≡1(modn)−kimod(n−k)≥2i≡0(modn)−k
所以这样就可以对于每个 k 做 O(n2) dp 了:
fi=j=1∑i(ji)fi−jhj
然后可以发现 h 中只有 O(n−kn) 个位置不为 0,所以可以调和级数,总复杂度变为 O(n2lnn)。
我们考虑对元素互不相同这个限制进行容斥,发现这个限制其实就相当于 ∀1≤i<j≤n,ai=aj。那么我们设 F(S) 表示对于一个集合 S 内的所有 (x,y) 都满足 ax=ay,那么答案就是 ∑S⊆En(−1)∣S∣F(S),其中 En 是直接暴力计算这个东西的时间复杂度为 O(n2∣En∣logm),过不去。
但是显然 F(S) 只和 S 中的边构成的连通块集合有关,所以我们考虑枚举划分集合进行 dp,设 fS 表示考虑了 S 集合内的答案,则有转移方程:
fS=T⊆S∑g∣T∣⌊lcm(T)m⌋fS−T
注意,我们为了不计算转移顺序的影响,必须要钦定编号最小的元素在 T 中。
其中 gn 表示 n 个点所形成的连通边集的容斥系数和。
考虑推导 g 是什么。类似连通图计数,可以得到转移方程:
gi=hi−j=1∑i−1(j−1i−1)gjhi−j
其中 hn 表示 n 个点所形成的任意边集的容斥系数和,则 hi=∑S⊆Ei(−1)∣S∣。
发现 h1=1,hi=0(i≥2),所以转移方程可以写成 g1=1,gi=−(i−2i−1)gi−1=−(i−1)gi−1,得出通项公式 gi=(−1)i−1(i−1)!。
则 O(n2nlogm) 预处理出每个子集的 lcm,O(3n) 枚举子集 dp 即可,也可以半在线子集卷积优化到 O(n22n),但是没必要。
推荐阅读:2023 论文《对互异关系的容斥》by 周子衡。