题解:P14270 ABC253Ex 加强版

news/2026/1/17 23:02:45/文章来源:https://www.cnblogs.com/P2441M/p/19497345

题意

有一张 \(n\) 个点的图,初始时图中无边。给定 \(m\) 条无向边,每次操作可以选择 \(m\) 条边中的一条加入图中。对于每个 \(i=1,\cdots,n-1\),求出加入 \(i\) 条边后图形成一个森林的方案数。\(2\leq n\leq 20\)\(1\leq m\leq 500\)

题解

考虑求出一个集合幂级数 \(F(x)\),其中 \([x^S]F(x)\) 表示 \(S\) 的导出子图的生成树个数。显然加入 \(i\) 条边后形成的森林由 \(n-i\) 棵树组成,因此答案就是

\[\sum_{k=1}^{n-1}(n-k)![x^U]\frac{F(x)^k}{k!} \]

\(F(x)\) 的求法这里暂且不作论述,不妨先考虑求出 \(F(x)\) 后如何计算答案。我们的问题是:给定集合幂级数 \(F(x)\),对于每个 \(k=1,\cdots,n-1\) 求出 \([x^U]\dfrac{F(x)^k}{k!}\)

考虑其组合意义就是对于每个 \(k\),求出将 \(U\) 拆分成 \(k\) 个无序集合的方案数,这里对于拆分出的每个集合 \(T\),其内部排列的方案数为 \([x^T]F(x)\)。套路地给拆分出的集合钦定顺序,按照 \(\max(T)\) 从小到大加入。考虑 DP,令 \(h_{i,j,S}\) 表示考虑到 \(\max(S)\leq i\)\(S\),将其拆分成 \(j\) 个部分的方案数。刷表转移:

  • 不加入 \(\max(S)=i+1\) 的集合:\(h_{i,j,S}\to h_{i+1,j,S}\)
  • 加入 \(\max(S)=i+1\) 的集合:设 \([x^S]F_i(x)=[\max(S)=i][x^S]F(x)\),则 \(h_{i,j}\times F_{i+1}\to h_{i+1,j+1}\),其中乘法为子集卷积。

枚举到 \(i\) 时,需要做 \(i\) 次规模为 \(2^i\) 的子集卷积,时间复杂度为 \(\mathcal{O}(\sum_{i=1}^n 2^ii^3)=\mathcal{O}(2^nn^3)\),无法通过。

注意到我们最终只关心 \(h_{n,k,U}\) 的值,考虑把这个 DP 倒着做,从 \(U\) 开始,按 \(\max(S)\) 从大到小删除集合,将状态定义改为:\(h_{i,j,S}\) 表示考虑从 \(U\) 开始,删除了 \(j\)\(\max(T)> i\) 的集合变成 \(S\) 的方案数,这里 \(\max(S)\leq i\)。转移是类似的:

  • 不删除 \(\max(T)=i\) 的集合:\(h_{i,j,S}\to h_{i-1,j,S}\)
  • 删除 \(\max(T)=i\) 的集合:\(h_{i,j,S}\times [x^T]F(x)\to h_{i-1,j+1,S-T}\),这里 \(\max(T)=\max(S)=i,T\subseteq S\)

考虑如何处理第二种转移。设 \(f_T=[x^T]F(x)\),首先将转移写作:

\[h_{i,j,S\cup\{i\}}\times f_{T\cup \{i\}}\to h_{i-1,j+1,S-T}\ (T\subseteq S) \]

\(\{i\}\) 略去,这实际上是子集差卷积的形式。使用类似多项式差卷积的手法,我们反转其中一个集合幂级数,具体来说,考虑令 \(h'_{i,j,S}=h_{i,j,\complement_US}\)(这里 \(U=\{1,\cdots,i-1\}\)),此时转移变成

\[h'_{i,j,S}\times f_T\to h'_{i-1,j+1,S\cup T}\ (S\cap T=\varnothing) \]

这就是标准的子集卷积的形式了!我们可以 \(\mathcal{O}(2^{i-1}(i-1)^2)\) 计算之。

注意到改变状态定义后,有 \(1\leq j\leq n-i\),这样枚举到 \(i\) 时,只需要做 \(n-i\) 次规模为 \(2^{i-1}\) 的子集卷积,时间复杂度降至 \(\mathcal{O}(\sum_{i=1}^n(n-i)2^{i-1}(i-1)^2)=\mathcal{O}(2^nn^2)\)

时间复杂度的证明

\(f(n)=\sum\limits_{i=1}^n(n-i)2^{i-1}(i-1)^2\),则有

\[f(n)=f(n-1)+\sum_{i=1}^{n-1}2^{i-1}(i-1)^2=f(n-1)+\mathcal{O}(2^nn^2) \]

因此 \(f(n)=\mathcal{O}(2^nn^2)\)\(\Box\)

计算答案时,取 \(h_{0,k,\varnothing}\) 即为我们所求。

现在我们会 \(\mathcal{O}(2^nn^2)\) 计算答案了,回到最初的问题:如何计算 \(F(x)\)

这里提供两种做法。

做法 1

\(f_S\) 表示 \(S\) 的导出子图的生成树个数。考虑到断开一条树边后会分裂成两棵子树,不妨枚举 \(T\) 表示分裂出 \(T,S-T\) 两棵子树,得到转移:

\[f_S=\frac{1}{2(|S|-1)}\sum_{\substack{T\subseteq S\\\min(S)\in T}}f_Tf_{S-T}\operatorname{cnt}(T,S-T) \]

其中 \(\operatorname{cnt}(T,S-T)\) 表示一端在 \(T\) 中,另一端在 \(S-T\) 中的边数。这里乘上 \(\dfrac{1}{2(|S|-1)}\) 是因为一棵树的每一条边都可以作为断边,而一棵子树会被作为 \(T\)\(S-T\) 枚举两次,因此一棵树恰好被重复计算 \(2(|S|-1)\) 次。

容斥一下可以得到 \(\operatorname{cnt}(T,S-T)=g_S-g_T-g_{S-T}\),其中 \(g_S\) 表示两端都在 \(S\) 中的边数。

因此转移可以被写作:

\[f_S=\frac{1}{2(|S|-1)}\left(g_S\sum_{\substack{T\subseteq S}}f_Tf_{S-T}-2\sum_{\substack{T\subseteq S}}f_Tg_Tf_{S-T}\right) \]

显然两个和式都是半在线子集卷积的形式,直接做即可。时间复杂度为 \(\mathcal{O}(2^nn^2)\),常数较大。

做法 2

还是令 \(f_S\) 表示 \(S\) 的导出子图的生成树个数,我们不去枚举断边,而是将 \(\max(S)\) 这个点删去,这样会分裂成若干棵不交的 \(\max(T)<i\) 的子树 \(T\)。据此考虑从小到大枚举 \(i\),每次更新 \(\max(S)=i\)\(f_S\)。构造集合幂级数 \(G(x)\),其中 \([x^T]G(x)=f_T\operatorname{cnt}(T,\{i\})\),我们对 \(G\)\(\exp\),然后容易得出 \(f_{S\cup\{i\}}=[x^S]\exp(G(x))\)

枚举到 \(i\) 时需要做一次规模为 \(2^{i-1}\)\(\exp\),时间复杂度为 \(\mathcal{O}(\sum_{i=1}^n2^{i-1}(i-1)^2)=\mathcal{O}(2^nn^2)\),常数较小。


这里给出做法 2 的主要代码。

主要代码
void OR(auto &a, int n, int tp) {int lim = 1 << n;for (int k = 1; k < lim; k <<= 1)for (int i = 0; i < lim; i += k << 1) for (int j = 0; j < k; ++j) {int *A = a[i ^ j ^ k], *B = a[i ^ j];for (int p = 0; p <= n; ++p) (tp == 1 ? cadd<int> : csub<int>)(A[p], B[p]);}
}void exp(int *a, int n) {static int b[N][21], c[N][21];for (int s = 0; s < 1 << n; ++s) memset(b[s], 0, n + 1 << 2), b[s][pc[s]] = a[s];OR(b, n, 1);for (int s = 0; s < 1 << n; ++s) {c[s][0] = 1;for (int i = 1; i <= n; ++i) {int val = 0;for (int j = 1; j <= i; ++j) cadd<int>(val, (ll)j * b[s][j] % MOD * c[s][i - j] % MOD);c[s][i] = (ll)val * inv[i] % MOD;}}OR(c, n, -1);for (int s = 0; s < 1 << n; ++s) a[s] = c[s][pc[s]];
}
void mul(int *a, int *res, int n) {static int b[N][21], tmp[21];int U = (1 << n) - 1;for (int s = 0; s < 1 << n; ++s) memset(b[s], 0, n + 1 << 2), b[s][pc[s]] = a[s ^ U];OR(b, n, 1);for (int s = 0; s < 1 << n; ++s) {memset(tmp, 0, n + 1 << 2);for (int i = 0; i <= n; ++i) for (int j = 0; j <= n - i; ++j)cadd<int>(tmp[i + j], (ll)b[s][i] * F[s][j] % MOD);memcpy(b[s], tmp, n + 1 << 2);}OR(b, n, -1);for (int s = 0; s < 1 << n; ++s) cadd(res[s], b[s ^ U][pc[s ^ U]]);
}int main() {ios::sync_with_stdio(0), cin.tie(0);cin >> n >> m;for (int i = 1, u, v; i <= m; ++i) cin >> u >> v, --u, --v, ++A[u][v], ++A[v][u];inv[1] = 1;for (int i = 2; i <= n; ++i) inv[i] = (ll)(MOD - MOD / i) * inv[MOD % i] % MOD;for (int s = 1; s < 1 << n; ++s) pc[s] = pc[s ^ lowbit(s)] + 1;t[1] = 1;for (int i = 1; i < n; ++i) {for (int s = 0; s < 1 << i; ++s) {int cnt = 0;for (int j = 0; j < i; ++j) if (s >> j & 1) cnt += A[i][j];t[s ^ (1 << i)] = (ll)t[s] * cnt % MOD;}exp(t + (1 << i), i);}h[0][(1 << n) - 1] = 1;for (int i = n - 1; ~i; --i) {for (int s = 0; s < 1 << i; ++s) memset(F[s], 0, i + 1 << 2), F[s][pc[s]] = t[s ^ (1 << i)];OR(F, i, 1);for (int j = n - i - 1; ~j; --j) mul(h[j] + (1 << i), h[j + 1], i);}for (int i = 1, fc = 1; i < n; ++i)fc = (ll)fc * i % MOD, cout << (ll)h[n - i][0] * fc % MOD << '\n';return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1175055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LDR6021Q实现充电加数据传输一个Type-c接口实现多功能同时进行

Type-C音频转接器、直播声卡、领夹麦等设备边充电边传输数据的实现原理与内部架构 随着科技发展&#xff0c;Type-C接口凭借其高效、兼容性强的特性&#xff0c;成为音频转接器、直播声卡、领夹麦等设备的核心接口。其核心功能——边充电边传输数据&#xff0c;依赖于内置的 US…

Git 入门:给你的代码装上“时光机”

Git 入门:给你的代码装上“时光机” 1. 背景与痛点(Why) 在接触 Git 之前,你可能经历过这样的场景: 写毕业论文或做项目方案时,为了防止改乱了回不去,你的文件夹里可能躺着这样一堆文件:论文_最终版.doc 论文_…

GoldenGate 19C的静默安装及打补丁 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

数字脉动:基于 Flutter × OpenHarmony 的图书馆管理系统统计信息模块构建实战

数字脉动&#xff1a;基于 Flutter OpenHarmony 的图书馆管理系统统计信息模块构建实战 前言 在数字化时代&#xff0c;图书馆不仅仅是书籍的存放地&#xff0c;更是知识管理和数据分析的重要节点。通过统计信息模块&#xff0c;管理员可以快速了解馆藏资源、读者情况以及借阅…

【课程设计/毕业设计】基于springboot的学车驾校线上学习课程安排管理系统的设计与实现【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【毕业设计】基于Java的博客系统基于springboot的博客系统(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

Java毕设项目:基于springboot的学车驾校线上学习管理系统的设计与实现(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

Java毕设项目:基于vue的博客系统基于springboot的博客系统(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

Java计算机毕设之基于springboot的驾校线上报名考试练车管理系统基于springboot的学车驾校线上学习管理系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【毕业设计】基于springboot的学车驾校线上理论学习刷题管理系统的设计与实现(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

Java计算机毕设之基于SpringBoot实现的社区博客管理系统基于springboot的博客系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【课程设计/毕业设计】基于SpringBoot+Vue的社会博客系统基于springboot的博客系统【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

YashanDB修改yasom管理端口的技术研究

我们的文章会在微信公众号IT民工的龙马人生和博客网站 ( www.htz.pw )同步更新 &#xff0c;欢迎关注收藏&#xff0c;也欢迎大家转载&#xff0c;但是请在文章开始地方标注文章出处&#xff0c;谢谢&#xff01; 由于博客中有大量代码&#xff0c;通过页面浏览效果更佳。 需求…

2 Mbps 到千兆级:WiFi 驱动工业场景的全面升级

回顾 WiFi 的发展历程&#xff0c;已从早期 2 Mbps 的 802.11b 基础版本&#xff0c;发展到如今的高性能 WiFi 5/6&#xff0c;具备更高带宽、/更低时延和更强的并发能力。这一演进不仅改变了大众的生活与娱乐方式&#xff0c;更为工业场景带来了前所未有的灵活性与可扩展性&am…

day137—链表—删除链表中的结点(LeetCode-237)

题目描述有一个单链表的 head&#xff0c;我们想删除它其中的一个节点 node。给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。链表的所有值都是 唯一的&#xff0c;并且保证给定的节点 node 不是链表中的最后一个节点。删除给定的节点。注意&#xff0c;删除节…

大数据领域数据共享的未来发展趋势

大数据领域数据共享的未来发展趋势&#xff1a;从“数据孤岛”到“数字共生”的进化之旅关键词&#xff1a;数据共享、隐私计算、联邦学习、区块链、数据要素市场、数据治理、数字经济摘要&#xff1a;在数字经济时代&#xff0c;数据已成为“新型石油”&#xff0c;但数据孤岛…

GESP认证C++编程真题解析 | 202409 二级

​欢迎大家订阅我的专栏:算法题解:C++与Python实现! 本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战! 专栏特色 1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的…

六.循环问题

1.角谷猜想#include<iostream> #include<string.h> #include<iomanip> using namespace std; int main() {int n;cin>>n;while(n>1){if(n%20) cout<<n/2<<endl;if(n%2!0) cout<<n*31<<endl;cout<<i<<endl; }…

洛谷 P2725:[USACO3.1] 邮票 Stamps ← BFS

​【题目来源】https://www.luogu.com.cn/problem/P2725https://www.acwing.com/problem/content/1382/【题目描述】给一组 n 枚邮票的面值集合和一个上限 k——表示信封上能够贴 k 张邮票。请求出最大的正整数 m,满足…

Apache Atlas vs DataHub:主流数据目录工具对比评测

Apache Atlas vs DataHub&#xff1a;主流数据目录工具对比评测关键词&#xff1a;数据目录、元数据管理、Apache Atlas、DataHub、对比评测、企业级数据治理、数据发现 摘要&#xff1a;本文深入对比分析Apache Atlas与DataHub两大主流数据目录工具&#xff0c;从技术架构、核…