当前位置: 首页 > news >正文

「清华集训2014-主旋律」题解

P11714 [清华集训 2014] 主旋律

pref

怎么新赛季就开始了。

一直想补岁月,但至今没有实现,也就只好先从主旋律下手。

我该在哪里停留?我问我自己。

sol

题意就是求删后原图仍强联通的有向边删边方案数。

强联通是不好刻画的,考虑非强联通。不难发现,其满足缩点之后是一个 DAG,先从 DAG 下手。

考虑刻画 DAG,不难想到拓扑,从而考虑到可以从入度为 \(0\) 的点入手,这些点删完之后得到的图仍然是 DAG,于是可以考虑从这里入手 DP。

令点集 \(S\) 的生成 DAG 方案数为 \(dp(S)\),记 \(f(T)\) 表示 \(S\) 内有且仅有 \(T\) 点集中的点入度为 \(0\) 的方案数,则有转移:

\[dp(S)=\sum_{\varnothing\subsetneqq T\subseteq S} f(T) \]

容斥求 \(f\),记 \(g(T)\) 为钦定 \(T\) 点集中的点入度为 \(0\) 的方案数,\(E_{S,T}\)\(S\) 点集连向 \(T\) 点集的边数,显然有:

\[g(T)=2^{E_{T,S-T}}dp(S-T) \]

则有:

\[f(T)=\sum_{T\subseteq R\subseteq S}(-1)^{|R|-|T|}g(R) \]

计算 \(dp(S)\)

\[\begin{aligned} dp(S)&=\sum_{\varnothing\subsetneqq T\subseteq S}\sum_{T\subseteq R\subseteq S}(-1)^{|R|-|T|}g(R)\\ &=\sum_{\varnothing\subsetneqq R\subseteq S}(-1)^{|R|}\sum_{\varnothing\subsetneqq T\subseteq R}(-1)^{|T|}g(R)\\ &=\sum_{\varnothing\subsetneqq R\subseteq S}(-1)^{|R|}(-[R=\varnothing])g(R)\\ &=\sum_{\varnothing\subsetneqq R\subseteq S}(-1)^{|R|+1}g(R)\\ &=\sum_{\varnothing\subsetneqq T\subseteq S}(-1)^{|T|+1}2^{E_{T,S-T}}dp(S-T) \end{aligned} \]

考虑拓展到缩点前的原图上,记 \(dp(S)\) 表示 \(S\) 是个 SCC 的方案数,\(g(T)\) 表示钦定 \(T\) 中点缩成若干入度为 \(0\) 的点的方案数,我们尝试仿照上面的式子写转移式,但不难发现容斥系数无法得到,其原因是无法得知 \(T\) 中的点到底缩成了几个入度为 \(0\) 的点。

考虑把容斥系数融入到 \(g\) 的定义中去,那么 \(g(S)\) 表示 \(S\) 中点缩成奇数个入度为 \(0\) 的点的方案数减去 \(S\) 中点缩成偶数个入度为 \(0\) 的点的方案数的值。在此之后求 \(g\) 其实也没有变得很困难,钦定一个子集视作新加入的来转移即可,强制令其包含 \(S\) 中某一个定点,比如 \(\mathrm{lowbit}(S)\) 代表元素,即可得到:

\[g(S)=dp(S)-\sum_{T\subset S\land \mathrm{lowbit}(S)=\mathrm{lowbit}(T)}dp(T)g(S-T) \]

也就是缩成一个 SCC 的方案数,减去新加 SCC 的方案数。后者是因为新加一个块块数奇偶性改变,相当于乘了一个容斥系数 \(-1\)

得到 \(g\) 之后即可得到 \(dp\)

\[dp(S)=2^{E(S,S)}-\sum_{T\subseteq S}2^{E_{T,S-T}+E_{S-T,S-T}}g(T) \]

特别的,当 \(S=T\) 时,\(g(S)\) 此时不应加上 \(dp(S)\),考虑组合意义理解一下即可。那么就是先算 \(g(S)\) 不加上 \(dp(S)\),再算得 \(dp(S)\),最后给 \(g(S)\) 加回去即可。

然后压力给到 \(E\) 的计算,这个东西现在状态数 \(4^n\),成为了瓶颈。然而不难发现,我们只会用到 \(E_{S,S},E_{T,S-T}\) 这两种形式的状态,故而状态数实际上只需要 \(3^n\)。考虑随 \(S\) 动态更新这两个东西,定义 \(I_v\) 为连向点 \(v\) 的点集,\(O_v\) 为点 \(v\) 连向的点集,每次钦定集合内一个点 \(u\)(比如 \(\mathrm{lowbit}\))转移即可,有:

\[E_{S,S}=E_{S-u,S-u}+|I_u\cap S|+|O_u\cap S|\\ E_{T,S-T}=E_{T+u,S-T-u}-|O_u\cap(S-T)|+|I_u\cap T| \]

于是这个问题结束了。最后复杂度为 \(O(3^n)\)

code

const int N=15,S=1<<N;int n,m;
int out[N],in[N],lg[S],e1[S],e2[S];
mint f[S],g[S],pt[N*N];inline void Main(){cin>>n>>m;pt[0]=1;rep(i,1,n*n)pt[i]=pt[i-1]*2;lg[1]=0;rep(i,2,1<<n-1)lg[i]=lg[i>>1]+1;rep(i,1,m){int a,b;cin>>a>>b;--a,--b;out[a]|=1<<b;in[b]|=1<<a;}repl(s,1,1<<n){int x=s&-s;e2[s]=e2[s^x]+__builtin_popcount(s&in[lg[x]])+__builtin_popcount(s&out[lg[x]]);}repl(s,1,1<<n){e1[s]=0;for(int t=s-1&s;t;t=t-1&s){int x=s-t&t-s;e1[t]=e1[t|x]-__builtin_popcount(s-t&out[lg[x]])+__builtin_popcount(t&in[lg[x]]);}for(int t=s-1&s;t;t=t-1&s){if((s&-s)!=(t&-t))continue;g[s]-=f[t]*g[s^t];}f[s]=pt[e2[s]];for(int t=s;t;t=t-1&s)f[s]-=g[t]*pt[e1[t]+e2[s^t]];g[s]+=f[s];}put(f[(1<<n)-1]);
}
http://www.zskr.cn/news/26727.html

相关文章:

  • 第二次高级程序作业
  • 大学生需要认真听课的肌肉记忆(注意力训练)
  • AWS IAM角色最佳实践:构建云安全的核心防线
  • 初始人工智能和机器学习
  • 盒子模型外边距合并问题
  • o(N^2)找出所有回文子串
  • 二叉树的中序遍历- 二叉树基本-栈 - MKT
  • 做了一个概率小游戏,没想到服务器被打爆被攻击了!原因竟然是他?真没想到...
  • 阿里云对象存储OSS之Java - Soul
  • Solidity合约继承场景下的构造函数执行顺序
  • 反数字化:线下活动也能年赚百万
  • sqlserver 主要的日期函数及用法示例
  • 图论刷题记录
  • 英语_备忘_疑难
  • 「JOISC2020-掃除」题解
  • CF简单构造小计
  • 软件工程第三次作业:四则运算题目生成器 - Nyanya-
  • Linux7种文件类型
  • AI代码生成技术解析与应用实践
  • 银河麒麟Kylin申威SW64系统安装 rpcbind-1.2.5-2.p01.ky10.sw_64.rpm 方法
  • 题解:P12525 [Aboi Round 1] 私は雨
  • 杂谈
  • 定位问题3:明明堆栈已经打印出来了,偏就是定位不出来?
  • 鸿蒙hdc命令【杭州多测师】
  • 电脑黑屏只剩鼠标-解决方案 - 教程
  • leetcode448. 找到所有数组中消失的数字
  • 揭开 C++ vector 底层面纱:从三指针模型到手写完整实现 - 指南
  • Java中的注释
  • 2025年栏杆护栏厂家权威推荐榜:不锈钢栏杆、桥梁防撞护栏、河道景观护栏专业制造商精选
  • Day1标签语法