「清华集训2014」主旋律
这个题好难难啊,我想了一个小时连50分都不会,只能去摸周指导了。
我们试图直接爆算集合 \(S\) 的非强连通导出子图数量,考虑将这个导出子图的所有强连通分量缩点后,一定是一个点数 \(\geq 2\) 的 \(\text{DAG}\) 。即缩完以后至少要有一个入度为 \(0\) 的点,这个条件充分性显然,必要性考虑如果不存在入度为 \(0\) 的点,那么一定存在一个环,说明并没有将所有强连通分量缩掉。然后我们枚举入度为 \(0\) 的点集 \(T\) ,记 \(F(T,k)\) 为将 \(T\) 划分成 \(k\) 个强连通分量的方案数,\(cnt(A,B)\) 表示集合 \(A\) 向 \(B\) 连边的数量。我们可以容斥算出不合法的方案数
\[
Q(S)=\sum_{T\subseteq S,T \neq \emptyset} (-1)^{k}F(T,k)2^{cnt(T,S-T)+cnt(S-T,S-T)}
\]
合法的方案数就是
\[
Ans(S)=2^{cnt(S,S)}-Q(S)
\]
简单解释一下这个式子,我们不太好直接确定所有入度为 \(0\) 的点,容斥枚举其中入度为 \(0\) 的点的一个子集,它对答案的贡献就是 \((-1)^k\) 剩下的边除了 \(T\) 内部不能再连以外都可以随便连,方案数就是后面那个。
这里要用到 \(F(T,k)\) ,其实它是打酱油的。事实上我们只需要对 \(k\) 按照奇偶性讨论,维护划分成奇数/偶数个强连通分量的方案 \(f(T,0),f(T,1)\) ,维护这个东西可以通过 \(Ans\) 来转移,为了避免算重,枚举一下 \(S\) 中编号最小的点处于哪一个强连通分量
\[
Q(S)=\sum_{T\subseteq S,T \neq \emptyset} [f(T,1)-f(T,0)]2^{cnt(T,S-T)+cnt(S-T,S-T)} \f(S,0)=\sum_{T \subseteq S, T \neq \emptyset}f(S-T,1)\times Ans(T) \f(S,1)=\sum_{T \subseteq S, T \neq \emptyset}f(S-T,0)\times Ans(T)
\]
这里存在一些相互转移的情况,但不难发现只有一个强连通分量时候虽然入度为 \(0\) 但是是合法方案,所以先处理 \(Ans\) 再更新 \(f\) 数组即可。
代码是膜别人的,就不贴了。
原文地址:https://www.cnblogs.com/mangoyang/p/11614344.html