P11834 [省选联考 2025] 岁月 题解

news/2025/3/20 15:17:05/文章来源:https://www.cnblogs.com/KellyWLJ/p/18783126

P11834 [省选联考 2025] 岁月 题解

状压图计数究极版本,好困难啊

感觉大家认为直接用概率做会简单一点,可我还是延续了场上计数的思路

定义与记号

\(U\) 表示全集,\(S/T\) 表示 \(T\subseteq S\) 时在 \(S\) 中且不在 \(T\) 中元素组成的集合

\(rt_s\) 表示点集 \(s\) 中能作为外向树的根的点的集合,即缩点后入度为 \(0\) 的唯一的强连通分量,连通块的根即指它

\(to_s\) 表示 \(s\) 中的点分别所在的连通块的所有点的并集

\(e(s,t)\) 表示一端点在 \(s\) 中,另一端点在 \(t\) 中的边的数量,\(e(s)\) 表示 \(s\) 中包含的边数,\(e(s,t)=e(s\cup t)-e(s)-e(t)\)

SCC 计数

类似的题是 P11714 [清华集训 2014] 主旋律

\(f_S\) 表示 \(S\) 中的点成为强连通分量的方案数,\(sum_s\)\(s\) 中点组成的图的方案数,\(sum_s=4^{e(s)}\)

考虑容斥,用所有图的数量减去强连通分量个数 \(>1\) 的方案数,而后者剥掉所有入度为 \(0\) 的强连通分量后仍非空,即能被划分为两部分

枚举划分出的拓扑序更小的一部分,即缩点后入度为 \(0\) 的强连通分量,假设钦定有 \(x\) 个,则容斥系数为 \((-1)^x\)

\(h_S\) 表示 \(S\) 中点划分为若干个强连通分量且带上容斥系数的方案数,每次新加入一个强连通分量 \(t\),注意每个集合固定一种加入顺序

\[h_s=\sum_{t\subseteq s,t\neq\varnothing}-f_t\times h_{s/t}[\max_{x\in t}x=\max_{y\in s}y] \]

\(f_s=sum_s-\sum_{t\subseteq s,t\neq\varnothing}h_t\times sum_{s/t}\times 2^{e(t, s/t)}\)

注意转移时 \(f_s\) 可以贡献给 \(h_s\),应该计算 \(f_s\) 后再 \(h_s\gets h_s-f_s\),初始化 \(h_{\varnothing}=1\)

时间复杂度为 \(O(3^n)\),瓶颈在于枚举子集

for(int i = 1; i < (1 << n); ++i) {int hb = 1 << __lg(i);for(int j = (i ^ hb); ; j = (j - 1) & (i ^ hb)) {int s = j ^ hb;Add(h[i], mod - 1ll * f[s] * h[i ^ s] % mod);if(j == 0)  break;}f[i] = sum[i];for(int j = i; j; j = (j - 1) & i) {int tmp = pw[num[i] - num[j] - num[i ^ j]]; // num[i] 即为 e(i)Add(f[i], 1ll * h[j] * sum[i ^ j] % mod * tmp % mod);}Add(h[i], mod - f[i]);
}

特殊性质 C

当所有边边权相同时,整张图只需要存在一棵外向树,这等价于将强连通分量缩点后只有一个入度为 \(0\) 的强连通分量

类似的,考虑容斥,钦定图中入度为 \(0\) 的强连通分量,设 \(g_{i,s}\) 表示 \(s\) 中的点被划分为 \(i\) 个入度为 \(0\) 强连通分量的方案数,可用类似于 \(h_s\) 的方法 \(O(3^nn)\) 转移

容斥系数是 \((-1)^{i-1}\times i\),原因是要使 \(\sum_{i=0}^x coef_i{x\choose i}=[x=1]\),可惜赛时离这个性质就差这个系数没求对

\[ans =\sum_{i=1}^n \sum_{s\subseteq U,s\neq\varnothing} (-1)^{i-1}i\times g_{i,s}\times sum_{U/s} \times 2^{e(s,U/s)} \]

实际上我们可以不记录个数,枚举当前入度为 \(0\) 的强连通分量 \(s\) 后枚举与它不相交的集合 \(t\),表示又钦定 \(t\) 中若干强连通分量也入度为 \(0\),那么若 \(t\) 中实际有 \(x\) 个强连通分量,要求 \(\sum_{i=0}^x coef_i{x\choose i}=[x=0]\),发现容斥系数又是 \((-1)^x\),则直接复用上面求出的 \(h_t\)

\[ans=\sum_{s\subseteq U,s\neq\varnothing}\sum_{t\cap s=\varnothing} f_s\times h_t\times 2^{e(s\cup t,U/(s\cup t))} \]

\(e(s)\) 可以做一遍高维前缀和求出,时间复杂度为 \(O(3^n+2^nn^2)\)

solution

考虑求无向图最小生成树的过程,将边从小到大排序后依次加入

受性质 B 的启发,我们一次性加入所有边权 \(=w\) 的边,如果某条边连接的两点在仅加入边权 \(<w\) 的边时就弱连通了,则这条边已经没用了,否则有可能成为最终方案中的一条边

于是可以分每种边权的边考虑,一次加入边权 \(=w\) 的边中符合要求的边

每次加入边后要求每个弱连通块中都可以形成外向树,而原来的弱连通块可以看成一个点,新加入的边要把这些点连成外向树且新加的边边权相同,这就转化为了类似于 C 性质的问题

\(e(s)\) 这里只考虑当前加入的边,\(e(s,t)\) 同理,注意后面 DP 数组的定义与前面不同

\(f_s\) 表示 \(s\) 中点恰好为 \(to_s\) 的根的方案数,这是我们每次要求的

\(sum_s\) 表示 \(s\) 仅满足 \(s\) 中的点恰好作为原来连通块的根时 \(to_s\) 的总数

\[sum_s=4^{e(to_s)}\sum_{t\subseteq s,t\neq\varnothing} f_t\times sum_{s/t}[\min_{x\in t}x=\min_{y\in s}y] \]

\(g_s\) 表示 \(s\) 中点在恰好作为原来连通块根的同时加入边后形成强连通分量的方案数

类比 C 性质,求出 \(h_s\) 表示 \(s\) 划分为若干个原来连通块根组成的强连通分量且它们入度为 \(0\),带容斥系数 \((-1)^x\) 的方案数

但与 C 性质很不同的一点是这里连通块看成点后的入度为 \(0\) 不是指没有边连向整个连通块,而是指没有边指向连通块的根

因此 \(h_s\)\(s\) 代表的若干个连通块之间的边也要算上方案数,恰好一端点在根的边不能有指向根的边,只有 \(2\) 种方案,端点均不在根的边可以任选

而且转移时要随时注意原来的连通块是一个整体,不能拆开为两部分分开加入,因此要每次都要判断两个集合 \(s,t\)\(to_s,to_t\) 无交,所有转移式中为了方便省略了

\[h_s=\sum_{t\subseteq s,t\neq\varnothing} -g_t\times h_{s/t}\times 2^{e(t,to_{s/t}/(s/t))+e(s/t,to_t/t)}\times 4^{e(to_t/t,to_{s/t}/(s/t))} \]

类比 SCC 计数中的方式,枚举 \(h_t\) 后剩下的连通块能随意连边,保持 \(t\) 入度为 \(0\) 即可

\[g_s=\sum_{t\subseteq s,t\neq\varnothing}h_t\times sum_{s/t}\times 2^{e(t,to_{s/t})}\times 4^{e(to_t/t,to_{s/t})} \]

令新求出的 \(f_s\)\(f'_s\) 以区分上一次得到的

设当前处理的加边后连通块全集为 \(U\),同理性质 C,求 \(f'_s\) 时枚举与它不相交的集合 \(t\)\(s\) 为目标中连通块根组成的入度为 \(0\) 的强连通分量,但钦定 \(t\) 中也有若干个这样的强连通分量,剩下的原来连通块的根任取,但每个连通块都得取出根

这样一看要枚举 \(3\) 个集合复杂度就爆炸了,但剩下的根显然只与 \(s\cup t\) 有关

因此预处理 \(dp_s\) 表示 \(U/s\) 中所有原来连通块取出根的总方案数,要算上 \(s\)\(U/s\) 的连边,枚举 \(U/s\) 中所有根的并集 \(t\)

\[dp_s=\sum_{t\cap s=\varnothing,to_t\cup to_s=U} sum_t\times 2^{e(s,to_j)}\times 4^{e(to_s/s,to_j)} \]

则可以求出 \(f'_s\),要算上 \(s,t\) 之间连边的方案数

\[f'_s=\sum_{t\cap s=\varnothing}h_t\times g_s\times dp_{s\cup t}\times 2^{e(s,to_t/t)+e(to_s/s,t)}\times 4^{e(to_s/s,to_t/t)} \]

最后只把发生更新的点集 \(s\)\(f_s\) 更新为 \(f's\),继续下一轮加边

答案为 \(ans=\sum_s f_s\),注意最后求概率要除以 \(4^k\) 而不是 \(4^m\)\(k\) 为加入的总边数

最多只会做 \(n\) 次,每次只计算了有新加入边的连通块,总的时间复杂度依然是 \(O(3^n+2^nn^2)\)

inline int in(int x, int s) {return (s >> (x - 1)) & 1;}
struct DSU {int pa[N], grp[N];void init() {for(int i = 1; i <= n; ++i)    pa[i] = i, grp[i] = 1 << (i - 1);}int find(int x) {return x != pa[x] ? pa[x] = find(pa[x]) : x;}void merge(int x, int y) {x = find(x), y = find(y);if(x != y)  pa[x] = y, grp[y] |= grp[x];}
}dsu, dsu2;
vector<int> subset(int s) {vector<int> res;for(int i = s; i; i = (i - 1) & s)  res.pb(i);reverse(res.begin(), res.end());    return res;
}
void solve(int l, int r) {memset(num, 0, sizeof(num)), memset(h, 0, sizeof(h)), memset(g, 0, sizeof(g)), memset(vl, 0, sizeof(vl));memset(book, 0, sizeof(book)), memset(to, 0, sizeof(to)), memset(sum, 0, sizeof(sum)), memset(tmp, 0, sizeof(tmp));int vis = 0;for(int i = l, x = ord[i]; i <= r; ++i, x = ord[i]) {vis |= dsu.grp[dsu.find(u[x])], vis |= dsu.grp[dsu.find(v[x])];num[(1 << (u[x] - 1)) | (1 << (v[x] - 1))] = 1;}vector<int> lin = subset(vis);for(int j = 0; j < n; ++j)for(int i = 1; i < (1 << n); ++i)   if((i >> j) & 1)    Add(num[i], num[i ^ (1 << j)]);for(int i = 1; i <= n; ++i) if(dsu.find(i) == i && ((vis >> (i - 1)) & 1)) {for(int j = dsu.grp[i]; j; j = (j - 1) & dsu.grp[i])  book[j] |= dsu.grp[i];}for(int i = 1; i < (1 << n); ++i)for(int j = 1; j <= n; ++j) if((i >> (j - 1)) & 1)  to[i] |= book[1 << (j - 1)];dsu2 = dsu;for(int i = l, x = ord[i]; i <= r; ++i, x = ord[i]) dsu2.merge(u[x], v[x]);sum[0] = g[0] = h[0] = 1;for(int i : lin) {int t = i & (-i);for(int j = (i ^ t); ; j = (j - 1) & (i ^ t)) {if(book[j ^ t] && (to[j ^ t] & to[i ^ j ^ t]) == 0) Add(sum[i], 1ll * sum[i ^ j ^ t] * f[j ^ t] % mod); if(j == 0)  break;}}for(int i : lin)    sum[i] = 1ll * sum[i] * pw4[num[to[i]]] % mod;auto get2 = [&](int i, int j) -> int { // i & j = 0     i -> jreturn num[i ^ j] - num[i] - num[j];};for(int i : lin) {int hb = 1 << __lg(i);for(int j = (i ^ hb); ; j = (j - 1) & (i ^ hb)) {int s = j ^ hb, t = i ^ s;if((to[s] & to[i ^ s]) == 0)    Add(h[i], mod - 1ll * g[s] * h[t] % mod * pw4[get2(to[s] ^ s, to[t] ^ t)] % mod * pw[get2(s, to[t] ^ t) + get2(t, to[s] ^ s)] % mod);if(j == 0)  break;}for(int j = i; ; j = (j - 1) & i) if((to[j] & to[i ^ j]) == 0) {Add(g[i], 1ll * h[j] * sum[i ^ j] % mod * pw[get2(to[i ^ j], j)] % mod * pw4[get2(to[j] ^ j, to[i ^ j])] % mod);if(j == 0)  break;}Add(h[i], mod - g[i]);}vl[0] = 1;for(int k = 1; k <= n; ++k) if(((vis >> (k - 1)) & 1) && dsu2.find(k) == k) {int S = dsu2.grp[k];vector<int> nw = subset(S);for(int i : nw) {int s = S ^ i;for(int j = s; j >= 0; j = (j - 1) & s) {if((to[j] & to[i]) == 0 && (to[j] | to[i]) == to[S])Add(vl[i], 1ll * sum[j] * pw[get2(i, to[j])] % mod * pw4[get2(to[i] ^ i, to[j])] % mod);if(j == 0)  break;}}for(int i : nw) {int s = S ^ i;for(int j = s; j >= 0; j = (j - 1) & s) { if((to[j] & to[i]) == 0)Add(tmp[i], 1ll * h[j] * g[i] % mod * vl[i ^ j] % mod * pw[get2(i, to[j] ^ j) + get2(j, to[i] ^ i)] % mod * pw4[get2(to[i] ^ i, to[j] ^ j)] % mod);if(j == 0)  break;}}}for(int i = 0; i < (1 << n); ++i)   if((i & vis) == 0)  tmp[i] = f[i];dsu = dsu2, memcpy(f, tmp, sizeof(f));
}
void mian() {read(n, m), ans = 0, pw[0] = pw4[0] = 1;memset(f, 0, sizeof(f));for(int i = 1; i <= m; ++i) read(u[i], v[i], w[i]), ln[i] = i;sort(ln + 1, ln + m + 1, [&](const int x, const int y){return w[x] < w[y];});for(int i = 1; i < (1 << n); ++i)   pcnt[i] = pcnt[i >> 1] + (i & 1);for(int i = 1; i <= m; ++i) pw[i] = add(pw[i - 1], pw[i - 1]), pw4[i] = 4ll * pw4[i - 1] % mod;dsu.init();for(int i = 1; i <= n; ++i) f[1 << (i - 1)] = 1;int tot = 0;for(int i = 1, j = 1; i <= m; i = j) {int cnt = 0;while(j <= m && w[ln[j]] == w[ln[i]]) {if(dsu.find(u[ln[j]]) != dsu.find(v[ln[j]]))    ord[++cnt] = ln[j], ++tot;++j;}if(cnt) solve(1, cnt);}for(int i = 1; i < (1 << n); ++i)   Add(ans, f[i]);ans = 1ll * ans * qmi(pw4[tot], mod - 2) % mod;print(ans), putchar('\n');
}

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

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

相关文章

JDK 24 发布,新特性解读!

真快啊!Java 24 这两天已经正式发布啦!这是自 Java 21 以来的第三个非长期支持版本,和 Java 22、Java 23一样。 下一个长期支持版是 Java 25,预计今年 9 月份发布。 Java 24 带来的新特性还是蛮多的,一共 24 个。Java 23 和 Java 23 都只有 12 个,Java 24的新特性相当于这…

解锁实时跌倒检测Jetson Nano与定制的YOLOv8

1. 概述 跌倒是一个重大问题,特别是对老年人和有疾病的人来说,因为它们可能导致严重伤害甚至死亡。坠落探测系统旨在迅速识别此类事件,确保及时提供援助并减少造成严重后果的风险。随着人工智能和机器学习的进步,跌倒检测变得更加准确和可靠。在我之前的博客中,“开始使用…

请求接口,接口响应中带回cookie,再请求其他接口后,cookie没有自动带入

最近做的项目,登陆时内部的登录,做个跳转,在那边登陆后会回跳到本地页面 本地联调接口,回调地址一直是提示跨域,然后再访问其他的接口提示401,未认证状态 从这个大哥中看到的问题,感谢 http://www.janron.net/details/8-computerLanguage-2326-488首先确定后端的接口resp…

Glyphs制作tff字体子集

官网 https://glyphsapp.com/zh 导出字体的子集 开发过程中整个字体文件太大,需要制作部分字体的子集合。 双击tff文件打开字体文件选择要保留的字符 •进入字体编辑窗口后,你会看到所有字符的网格。 •按住 Cmd 键并点击你想要保留的字符。 例如:大小写字母、数字、特殊符号…

开启MySQL8的密码策略组件validate_password.250320

一、validate_password组件安装配置安装组件INSTALL COMPONENT file://component_validate_password;安装后,密码策略立即生效,但仅影响后续操作(如新建用户或修改密码)。卸载组件UNINSTALL COMPONENT file://component_validate_password;卸载后,密码复杂度策略失效,可设…

茶聚场日事清实战案例:OKR目标管理+流程优化+看板会议系统深度应用

茶聚场通过引入日事清管理系统,有效解决了OKR不透明、跨区域协作低效及供应链管理分散等挑战,实现了目标对齐、流程优化与运营效率提升,支撑其在新茶饮市场的战略扩张。公司介绍 在2016年,一个新的品牌诞生在北京的商业心脏地带——茶聚场。作为茶聚场(北京)餐饮管理有限…

20250320日

01.军工 02.纳指etf 03.煤炭:04.红利etf 05.养殖ETF:06.白酒:

勤策、玄瞳、纷享销客对比,消费品领域CRM厂商怎么选?

近年来,随着消费品行业竞争加剧,CRM(客户关系管理)系统已成为企业提升运营效率、增强客户满意度的关键工具。其中,纷享销客、勤策、玄瞳等作为该领域的佼佼者,各自拥有独特的产品特点和适用企业类型。本文将此前三家主流快消领域CRM厂商进行全面对比,帮您理清各家厂商“…

Deepseek本地部署的webui可视化

1.WebUI可视化插件 —— Page Assist 在chrome应用商店中搜索Page Assist,找到后添加到chrome 浏览器添加完成后类似这样 点击这个扩展插件,即可看到 就可以进行对话聊天了

母婴电商企业案例:日事清驱动项目管理执行与OKR目标管理的流程自动化实践

日事清以电商基因与高性价比集成方案,助力科木电商解决协作低效、流程散乱等管理痛点,实现母婴品牌“小鹿豆豆”的团队提效与目标追踪。一、关于科木电商“小鹿豆豆”,一个年轻的品牌,近期在无论是淘宝、拼多多还是抖音电商平台,都成了亮眼的爆品。这个由绵阳科木电子商务…

20241905 2024-2025-2 《网络攻防实践》 第4次作业

1. 实验内容 在网络攻防实验环境中完成TCP/IP协议栈重点协议的攻击实验,包括ARP缓存欺骗攻击、ICMP重定向攻击、SYN Flood攻击、TCP RST攻击、TCP会话劫持攻击。 ARP缓存欺骗攻击:ARP协议在进行IP到MAC地址映射查询时存在安全缺陷,ARP协议为提高效率,设置了缓存机制,会将主…

ClkLog埋点系统客户案例-电子签佼佼者「大家签」为何选择ClkLog?

ClkLog的付费版上线已有一年多。作为一款从开源起步的产品,我们始终关注用户的使用体验。因此,近期我们发起了一轮客户回访,希望了解他们的使用情况及优化建议,并分享一些典型案例,让更多人看到ClkLog在真实业务场景中的价值。本次回访的客户是ClkLog最早的一批付费用户—…