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

28 S2模拟赛T2 开会council 题解

council

题面

给定一棵 \(n\) 个节点的树,每个节点有黑白两种颜色,还有 \(k\) 个特殊节点。

距离表示两个点间路径上边权的最大值。

我们每次指定一个白点,对于每个黑点,设 \(disb\) 表示其到任意一个特殊点距离的最小值,设 \(disa\) 表示此特殊点到指定白点的距离。

这个白点对答案的贡献即为 \(\sum \max (disa, disb)\)

但是有一个点的颜色不太稳定,可能由黑变白,也可能由白变黑。

你的任务是求出没有点变色的答案,以及对于每个点,其变色并且其余点不变色的答案。

\(1 \le n \le 2\times 10^5\)

题解

这道题条件很多,我们需要谨慎处理。

我们先不考虑 \(disb\) 的影响,假设每个点本身就是一个特殊点,也就是只有 \(disa\),是比较好做的。

因为每个点可能变色,所以我们要考虑一个黑点变成白点的情况。

对于每个点我们记 \(f(i,0/1)\) 表示所有白/黑点到 \(i\) 的距离和,朴素的做法是 \(O(n^2)\) 暴力跑出来。

考虑如何优化这个东西

因为我们每次都是求路径上的边权最大值,所以我们可以将树重构。

也就是从小到大枚举每条边 \((x,y,z)\),然后将 \(x,y\) 所属的连通块尝试连接起来,如果两个连通块不连通,那么 \(z\) 就会成为两个连通块的点之间的最大权值。

对每个连通块,我们记 \(siz_{fx, 0}, siz_{fx, 1}\) 分别表示白点和黑点数量,以及 \(tag_{fx,0}, tag_{fx, 1}\) 表示对连通块中的点的白黑贡献。

我们每次合并两个连通块的时候按秩合并,也就是将小的合并到大的里边。对于大块中的点,我们直接打标记,对于小块中的点,我们将其标记下放并插入到大块中。

对于每个点来说至多合并 \(O(\log n)\) 次,所以合并的时间复杂度 \(O(n \log n)\)

然后我们来处理到特殊点距离的最小值。

在这之前,我们要说明一个结论,假设起点为 \(x\),特殊点为 \(z\),白点为 \(y\)。路线 \(x \to z \to y\)\(x \to z \to x \to y\) 这两种情况的贡献是相同的。

假设我们不考虑 \(x \to z\) 相同的一段,那么也就是比较 \(z \to y\)\(z \to x \to y\) 的边权最大值,因为后者多饶了个弯,所以后者的贡献大于等于前者。

同理,我们也可以得出前者的贡献大于等于后者,所以前者的贡献就等于后者。

image-20251013210513798

所以我们分别考虑 \(x \to z\)\(x \to y\) 的贡献即可。

首先,我们可以先跑个多起点最短路算一下每个点到特殊点的距离最小值 \(dis_i\),时间复杂度 \(O(n \log n)\)

然后我们进行一个很巧妙的操作,从而将这个东西合并到我们刚才的操作中。我们不是要取这两者的最大值吗,发现这个好像和刚才的路径最大边权有点相似,考虑能否将这个到特殊点的距离也当做一个边权?

实际上是可以的,对每个点建一个新点,原点和新点之间的边权即为 \(dis_i\)

如果原点为黑点,我们设原点为无色点,新点为黑点。

否则原点为白点,新点为无色点。

image-20251013211902735

然后我们将这个新边加上即可进行统计。

总时间复杂度为 \(O(n \log n)\)

具体加加减减可以手模,具体实现看代码。

code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>using namespace std;namespace michaele {typedef long long ll;const int N = 4e5 + 100, M = N << 1;int n, k;int h[N], ver[M], ne[M], e[M], tot;int kd[N], sta[N];int fa[N], siz[N][2];ll f[N][2], tag[N][2], dis[N];bool vis[N];vector <int> st[N];struct edge {int x, y;ll z;bool operator < (const edge &t) const {return z < t.z;}};vector <edge> E;void add (int x, int y, int z) {ver[ ++ tot] = y;ne[tot] = h[x];h[x] = tot;e[tot] = z;}int fin (int x) {return x == fa[x] ? x : fa[x] = fin (fa[x]);}void dijk () {priority_queue <pair <ll, int> > q;for (int i = 1; i <= k; i ++) {q.push ({0, sta[i]});dis[sta[i]] = 0;}while (q.size ()) {int x = q.top ().second;q.pop ();if (vis[x]) continue;vis[x] = 1;for (int i = h[x]; i; i = ne[i]) {int y = ver[i];if (dis[y] > max (dis[x], (ll)e[i])) {dis[y] = max (dis[x], (ll)e[i]);q.push ({-dis[y], y});}}}}void clear () {tot = 0;int size = (n + 5) << 1;memset (h, 0, size * 4);memset (vis, 0, size);memset (dis, 0x3f, size * 8);memset (siz, 0, size * 4 * 2);memset (tag, 0, size * 8 * 2);memset (f, 0, size * 8 * 2);E.clear ();for (int i = 1; i <= n * 2; i ++) {vector <int> emp;st[i].swap (emp);}}void solve () {cin >> n >> k;clear ();for (int i = 1; i <= n; i ++) {cin >> kd[i];}for (int i = 1; i < n; i ++) {int x, y, z;cin >> x >> y >> z;add (x, y, z);add (y, x, z);E.push_back ({x, y, z});}for (int i = 1; i <= k; i ++) {cin >> sta[i];}dijk ();for (int i = 1; i <= n; i ++) {fa[i] = i, fa[i + n] = i + n;st[i].push_back (i);st[i + n].push_back (i + n);if (kd[i]) siz[i + n][1] = 1;else siz[i][0] = 1;E.push_back ({i, i + n, dis[i]});}sort (E.begin(), E.end ());for (auto p : E) {int fx = fin (p.x), fy = fin (p.y);if (fx == fy) continue;if (siz[fx][0] + siz[fx][1] < siz[fy][0] + siz[fy][1]) {swap (fx, fy);}fa[fy] = fx;tag[fx][0] += (ll)p.z * siz[fy][0];tag[fx][1] += (ll)p.z * siz[fy][1];for (auto t : st[fy]) {f[t][0] += tag[fy][0] + (ll)p.z * siz[fx][0] - tag[fx][0];f[t][1] += tag[fy][1] + (ll)p.z * siz[fx][1] - tag[fx][1];st[fx].push_back (t);}siz[fx][0] += siz[fy][0];siz[fx][1] += siz[fy][1];}int ff = fin (1);for (int i = 1; i <= n * 2; i ++) {f[i][0] += tag[ff][0];f[i][1] += tag[ff][1];}ll ans = 0;for (int i = 1; i <= n; i ++) {if (kd[i]) ans += f[i + n][0];}cout << ans << endl;for (int i = 1; i <= n; i ++) {if (kd[i] == 0) {cout << ans - f[i][1] + f[i + n][0] - dis[i] << endl;} else {cout << ans - f[i + n][0] + f[i][1] - dis[i] << endl;}}}void Main () {int T;cin >> T;while (T --) {solve ();}}
}int main () {michaele :: Main ();return 0;
}
http://www.hskmm.com/?act=detail&tid=32352

相关文章:

  • 25 LCA模拟赛3T1 ROI 2012马赛克 题解
  • 实验记录2025/10/14
  • 个人微信开发框架
  • 投资指标技术分析
  • linux源码编译python
  • uni-app x开发商城系统,Swiper 轮播图
  • 昂瑞微OM6651A:国产车规级蓝牙芯片的破局者
  • 2025年中央空调/锅炉房/机房运维服务厂家最新权威推荐榜:专业托管与维修外包一体化解决方案精选
  • 【终极解决方案】api-ms-win-core-path-l1-1-0.dll 缺失?Win7/Win10/Win11完整修复教程
  • 2025 年最新推荐分切机实力厂家权威榜单:覆盖全自动高速、铝箔、薄膜、高精度等机型,为软包装企业精选优质设备
  • 打破应用跳转流失困局,提升推广链接转化率
  • 性能测试进阶秘籍:如何用JMeter分布式压测挖掘系统极限潜
  • Codeforces Round 1058 (Div. 2) A~E
  • 2025 年生料带厂家最新推荐排行榜:解析优质品牌优势,涵盖新型、彩色、液态等多类型生料带厂家企业推荐
  • openresty开发lua-resty-openssl之对称加密解密 - liuxm
  • 哈希乱搞:CF1418G Three Occurrences
  • 2025 年废旧轮胎裂解加热生产厂家最新推荐榜单:优质企业专利技术、产能规模与口碑实力全景解析锂化工焚烧炉/氟化热风系统/煤化工热风炉厂家推荐
  • 悲伤 自卑 乖戾 独自哭泣 陪伴空虚 kill my memory 让我将痛苦全忘记
  • 日志 | 2025.10
  • 工程师的 “指尖实验室”!正点原子 LT1 电桥镊子深度测评:同价位竞品谁能打?
  • 【ACM出版|EI检索稳定】2025年AI驱动下:业务转型和数据科学创新国际学术会议(ICBTDS 2025)
  • 破解跨域监控难题:国标GB28181算法算力平台EasyGBS视频调阅技术在跨域安防监控中的核心应用
  • 2025 年电缆桥架源头厂家最新推荐排行榜:聚焦优质供应商核心竞争力,助力工程采购精准选型
  • 2025 年厂房出售公司服务推荐排行榜:珠三角/广州/深圳/东莞/佛山/珠海等城市优质厂房出售公司全面测评解析
  • 构建智能视觉中枢:国标GB28181算法算力平台EasyGBS的全域感知与播放方案
  • 别再乱排查了!Kafka 消息积压、重复、丢失,根源基本都是 Rebalance!
  • 2025年交通杯-爆破题wp
  • 挖象浏览器下载安装教程|支持淘宝、拼多多、抖音多平台账号分区管理
  • 2025 年国内活性炭回收交易公司最新推荐排行榜:实力厂商深度解析,助力企业精准选合作方回收果壳活性炭/回收煤质柱状活性炭/库存各种活性炭公司推荐
  • 2025-10-15 CSP-J 模拟赛 赛后总结【ZROI】