正能量的dp——状压/容斥

总结

容斥

这部分的容斥主要是 DAG 上的,本质上是子集反演。基本上就是枚举一层的点集合,然后根据实际情况计算系数。

题目

P6846

首先发现将一张 DAG 的边全部反向,仍然是一张 DAG。并且这两种改边总和是 \(m\)。所以答案就是 \(m\) 乘定向 DAG 方案数除以二。

考虑一个 DAG 的特征,考虑剖成若干层入度为 \(0\)。这启发我们考虑一种计数,设 \(f_{S}\) 表示 \(S\) 是 DAG 的方案数,转移就找到一层,则要求这一层显然是一个独立集。所以

\[f_S=\sum_{T\subset S,T\ne \varnothing}f_{S\setminus T}2^{E_{T\to S\setminus T}}[T\text{ is an IS}] \]

发现这样显然会算重,因为可能 \(S\setminus T\) 还有 \(0\) 入度点,所以设 \(F(A)\) 表示钦定 \(A\) 是独立集的算出来的系数即 \(f_{S\setminus A}2^{E_{A\to S\setminus A}}\)\(G(A)\) 表示独立集恰好是 \(A\) 的方案数,所以有

\[\begin{aligned} F(A)&=\sum_{A\subset B}G(B)\\ G(A)&=\sum_{A\subset B}(-1)^{|B|-|A|}F(B)\\ f_S&=\sum_{T\subset S,T\ne\varnothing}G(T)\\ &=\sum_{T\subset S,T\ne \varnothing}\sum_{T\subset A\subset S}(-1)^{|A|-|T|}F(A)\\ &=\sum_{A\subset S}F(A)(-1)^{|A|}\sum_{T\subset A,T\ne \varnothing}(-1)^{|T|}\\ &=\sum_{A\subset S}F(A)(-1)^{|A|+1} \end{aligned} \]

相当于只需在原本的式子上乘上一个 \((-1)^{|T|+1}\) 的系数。或者直观理解就是容斥原理。\(A\cup B=A+B-A\cap B\)。所以时间复杂度 \(O(3^n)\)

A

首先如果原图不是一个 SCC,那么缩点之后就是一个 DAG。所以这个题跟上一题有很大的相似之处。

\(f_{S}\) 表示 \(S\) 不是强联通的方案数,相当于就是缩点后是 DAG。那么跟上题一样,枚举一个集合,由于你不知道它缩点后有几个独立集,所以再设 \(g_{S,i}\) 表示 \(S\) 缩点后是 \(i\) 个独立集的方案数,那么类似上道题有

\[f_S=\sum_{T\subset S,T\ne \varnothing}\sum_{i=1}^{|T|}g_{T,i}2^{E_{S\setminus T}+E_{T\to S\setminus T}}(-1)^{i+1} \]

其中 \(2^{E\setminus T}\) 是因为这个集合里的边是可以乱连不用保证是一个 DAG 的,因为 \(S\) 一定不是一个 SCC。

然后这个转移是有点问题的,当 \(T=S\) 时会多算 \(g_{T,1}\),而这个相当于 \(S\) 是一个 SCC 了,所以不能算上。并且 \(g_{S,1}=2^{E_S}-f_S\),需要算出 \(f_S\) 才能求出,所以避免了自转移的情况。\(g_{S,i\ge 2}\) 是好求的。

然后时间复杂度就是 \(O(3^nn)\) 了,但是注意到可以直接将 \((-1)^{i+1}\) 系数记进 \(g_{T}\),于是就做完了。

\[f_S=\sum_{T\subset S,T\ne \varnothing}g_{T}2^{E_{S\setminus T}+E_{T\to S\setminus T}}\\ g_S=2^{E_S}-f_S\ {\color{red}-}\sum_{T\subset S,\text{lowbit}(T)=\text{lowbit}(S),T\ne S}(2^{E_T}-f_T)g_{S\setminus T} \]

\(\color{red}-\)\(-1\) 的系数。

E

答案显然不会超过 \(n\)。考虑怎么用操作二节省次数。容易发现一定是若干集合 \(S\) 使用 \(|S|-1\) 次操作二变成全 \(0\),因为如果 \(\ge |S|\) 不如全用操作 \(1\)\(<|S|-1\) 一定可以继续拆。然后剩下的数使用操作一变成 \(0\)

为了让答案最小,即让这样的 \(S\) 最多。考虑将操作二的两个数连边以刻画操作,那么根据上面的结论一定是 \(S\) 是树时最优。先考虑怎样的 \(S\) 是合法的。

先考虑弱化问题,每次选两个数 \(-x\),随便钦定一个点作为树的根,那么考虑剥叶子,只需要最终根的权值为 \(0\) 即可。发现奇数层的对根的贡献为 \(+\),偶数层的贡献为 \(-\),于是奇数层的权值和与偶数层的权值和相等是 \(S\) 合法的充要条件。进一步,这个等价于找到一个子集 \(T\),使得 \(T\) 的权值和等于 \(S\setminus T\) 的权值和,因为是一定能还原成一棵树的。

现在变成一个 \(-x\) 一个 \(-x-1\)。相当于在刚刚基础上,再执行 \(|S-1|\) 次操作,每次让奇数层或者偶数层的权值 \(+1\),然后最终权值和相等。形式化的就是找到子集 \(T\) 使得 \(|s(T)-s(S\setminus T)|\le |S|-1\) 并且 \(|s(T)-s(S\setminus T)|\equiv |S|-1\pmod 2\),因为更改一次操作差就会变化 \(2\)。也即 \(s(S)\equiv |S|-1\pmod 2\)

那么判合法时间复杂度就是 \(2^{|S|}\),对于所有 \(S\) 判就是 \(3^n\),常数有点大考虑优化。比较经典的就是折半,将两边排序后就可以双指针扫一遍了,问题在于排序,是 \(O(\sqrt 2^{|S|}|S|)\) 的,然后发现考虑每次往集合加入一个数,是可以归并排序的,所以就去掉了 \(|S|\),总时间复杂度就是 \(\displaystyle\sum_{i=0}^{n}\binom{n}{i}\sqrt 2^i=(\sqrt 2+1)^n\)

然后就基本上做完了,直接做一遍 \((\max,+)\) 子集卷积就可以算出最多 \(S\) 的数量,是一个常数小的 \(3^n\),所以就能通过了。当然也可以倍增+子集卷积做到 \(O(2^nn^2\log n)\),意义不大。

技巧:

  • 子集折半
  • 二元组考虑建图
  • 奇偶分层

C

首先答案显然是不会超过值域的。然后分析一下,如果确定了回应观众的集合,那么最优策略肯定是,选择当前 \(B\)\(\le a_i\) 的最大数替换成 \(a_i\),如果不存在就新加一个元素。或者也可以将原问题用 Dilworth 变成划分最少的不降子序列。

发现 \(B\) 中元素一定是互不相同的。于是便能设计出一个 dp,\(f_{S,i}\) 表示当前 \(B\) 元素组成集合为 \(S\),考虑前 \(i\) 个并钦定第 \(i\) 个观众回应是否可行,于是便能做到 \(O(2^Vn)\)

\(f_{S,i}\) 值域只有 \(0,1\),所以考虑交换状态和值域,事实上最终答案只关心有哪些 \(f_{S,n/n-1}=1\),所以只需要关注 \(S\) 能到最远的 \(i\)。即设 \(g_{S}=\max\limits_{f_{S,i}=1}i\)

然后发现转移有自环,即如果当前 \(g_S=p\),如果 \(a_{p+1}\in S\),那么可以继续拓展;否则如果 \(a_{p+2}\in S\),也是可以继续拓展的。因为新到的 \(S'\) 是等于 \(S\) 的。所以只需找到最小的 \(a_i,a_{i+1}\not \in S\)\(i\),可以通过一些方法做到 \(O(2^VV^2+nV)\),但这不是重点。

  • 交换值域与状态

F

考虑对于一个选取的集合 \(S\),假设能让只选 \(S\) 合法的最大长度是 \(f_S\),那么显然其合法的长度就是 \(\left[\sum_{i\in S}a_i,f_S\right]\) 这个区间,可以通过调整得到。于是只要求出 \(f_S\),便能求出答案。

相当于有一个集合 \(T\) 不能选,如果我们直接设状态 \(f_S\) 表示选取的数是 \(S\),不能选的是 \(\complement_U S\),发现假设当前要选 \(i\in S\),相当于 \(S\) 就被分成了两个部分,即放 \(i\) 左边的 \(S_1\) 和右边的 \(S_2\)。发现 \(S_1\) 在选的过程中只是要求不能选 \(\complement_U S\) 而非 \(\complement_U S_1\),所以这个做法就有问题。

所以就要记 \(f_{i,S,T}\) 表示要选 \(S\) 里的数,不能选 \(T\) 里的数所占据的最长长度,当前考虑的数是 \(a_i\),分情况考虑一下

  • \(i\in T\),那么 \(f_{i,S,T}=\min(a_i-\epsilon,f_{i+1,S,T})\),这是因为 \(i\) 要先放,如果长度 \(\ge a_i\) 就不合法了。
  • \(i\in S\),那么 \(f_{i,S,T}=a_i+\displaystyle\max_{S_1\cup S_2=S\setminus \{i\}}\left\{f_{i+1,S_1,T}+f_{i+1,S_2,T}\right\}\)
  • 否则不用管,\(f_{i,S,T}=f_{i+1,S,T}\)

考虑 \(\epsilon\) 的问题,注意到最后答案一定是一个左闭右开区间,所以不需要管,最后让 \(f_S>m\) 就行了。

  • 观察划分产生的子问题
posted @ 2025-12-20 16:52  _chara  阅读(46)  评论(2)    收藏  举报
Title