「Solution」AGC008F Black Radius

news/2025/11/18 20:36:06/文章来源:https://www.cnblogs.com/in-silence/p/19239230

很好玩的题目!没有想到题解区做法,这里给一个鏖战许久的容斥做法。由于写的太多所以单独成篇了。

这个关键点、距离等限制有一种 [十二省联考 2019] 希望 的既视感(虽然这个题更早)。直接算单个点的贡献就是以其为根时的最大深度,直接加起来会算重。

和希望那题一样,猜测对于一个树上连通块 \(S\),能染出来 \(S\)\(u\) 在树上也是一个连通块。这应该是容易证明的,具体在下面的求解过程中也可以感知到。


先考虑 \(s_i=1\) 怎么做。

考虑容斥,可以直接套点边容斥,就是只需要算点的方案数减去边的方案数。更多关于这个结论的内容可以去希望的题解区。

点的方案数上面提过了,就是以其为根时的最大深度(根的深度为 \(1\))。

至于边的方案,考察树上一条边 \((u,v)\),其中 \(u\)\(v\) 的父亲:

\(x\) 表示在 \(v\) 子树外一点到 \(u\) 的最大距离,\(y\) 表示在 \(v\) 子树内一点到 \(v\) 的最大距离。考虑选择 \(v,d_v\) 进行染色,是否存在 \(d_u\) 使得选择 \(u,d_u\) 染色的方案一样。建议画图感知一下下面的分讨。

  • \(d_v<y\),此时必须有 \(d_u=d_v+1\),否则在 \(v\) 子树内的染色情况不同。那么这时必须要求 \(d_v\geq x+1\),否则在 \(v\) 子树外的染色情况不同。这种情况的方案数为 \(\max(0,y-x-1)\)

  • \(d_u<x\),此时必须有 \(d_v=d_u+1\),否则在 \(v\) 子树外的染色情况不同。同时有 \(d_u\geq y+1\),否则在 \(v\) 子树内的染色情况不同。这种情况的方案数为 \(\max(0,x-y-1)\),可以看到和上面那种情况是恰好互补的。

  • \(d_u=d_v\),这是唯一剩下的没有被上面讨论到的情况。此时取 \(d_u=d_v=\max(x,y)\) 是唯一解,方案数为 \(1\)

综合一下几种情况,一条边 \(u,v\) 的方案数为 \(\max(1,|x-y|)\)

自此解决了 \(s_i=1\) 的点,发现非常良心地有这档分(于是我以为我的思路是正解思路)。Code。


接下来考虑原题目。

原题目由于指定了关键点,容斥会有点麻烦。具体来说,不妨回归本源,钦定一些关键点 \(S\),算 \(S\) 合法的方案数并带上系数 \((-1)^{|S|-1}\)

由于 \(|S|\) 合法等价于 \(|S|\) 的斯坦纳树合法,因此可以以树上连通块为计数对象。可以得到当且仅当一个树上连通块的叶子(度数 \(=1\))全都是关键点,且非叶点全都不是关键点的时候会有贡献。至于为什么是这样,在这里有详细的阐释。

将连通块上的所有点依次标号为 \(v_1,v_2,\cdots,v_k\)。令 \(v_i\) “子树”外最大距离为 \(x_i\),“子树”内最大距离为 \(y_i\)。在此定义 \(v_i\) 的“子树”:对于一个点 \(w\),如果 \(v_i\rightarrow w\) 的路径上经过了除 \(v_i\) 以外的连通块上的点,\(w\)\(v_i\) 的“子树”外,否则在 \(v_i\) 的“子树”内。

再设 \(v_i\)\(d_i\) 进行染色时 \(k\) 个点的染色结果相同。

从上面 \(s_i=1\) 的做法可以看出,只可能存在至多一个 \(i\) 满足 \(d_i<y_i\),在 \(d_i\) 确定后所有的 \(d\) 都确定了。同时有 \(d_i\geq x_i\),即 \(v_i\) 可以染到外面的所有点,否则外面的点染色情况不同。总的贡献为 \(\max(0,y_i-x_i)\)

于是可以发现对于一个连通块真正产生贡献的其实只有一个 \(v_i\),即 \(y_i\) 最大的那个。因为要求了 \(x_i\leq d_i< y_i\),又有 \(\forall i,j(i\not=j),x_i\geq y_j\),所以只有 \(y_i\) 最大的那个会产生贡献。注意到一个更强的说法是一个连通块内至多只有一个点满足 \(y_i>x_i\)

Caution:这里需要注意的是连通块的根如果是关键点,度数必须为 \(1\),否则度数必须不为 \(1\),不然与斯坦纳树的定义相悖。在下面的讨论中,默认这一条件已经考虑。

于是考虑分开计算每个满足 \(y>x\) 的点 \(u\) 的贡献。

  • 对于一个在连通块上不为根的关键点 \(u\) 来说,如果其子树外存在其它关键点,其容斥系数之和为 \(-1\),否则为 \(0\)。这是因为假设其子树外有 \(c\) 个关键点满足到 \(u\) 的路径上没有其它关键点,容斥系数为 \(\sum\limits_{i=1}^c(-1)^{i}\binom{c}{i}=-[c\not=0]\)

  • 对于一个在连通块上为根的关键点来说,如果其子树内存在其它关键点,其容斥系数之和为 \(-1\),否则为 \(0\)

  • 对于一个在连通块上的非关键点 \(u\) 来说——这是最麻烦的情况,因为其“子树”内外的最大距离是不确定的——先再明确一遍其“子树”的定义:如果一个点到 \(u\) 的路径上经过了除 \(u\) 以外的连通块上的点,这个点在 \(u\) 的“子树”外,否则在 \(u\) 的“子树”内。由于子树内最大距离大于子树外最大距离才会产生贡献,\(u\) 儿子(这里暂且以 \(u\) 为根,就是将其原树上的父亲也视为儿子)的子树当中最大距离最大的那个一定会被划分到 \(u\) 的“子树”内,而其它的儿子可以随意划分(当然只有在其子树内有关键点的时候才能被划分到 \(u\) 的“子树”外)。然后再枚举“子树”外的最大距离计算贡献。假设“子树”外最大距离为 \(d\),则考察是否存在至少两个子树内最大距离 \(\leq d-1\) 的儿子有关键点,有的话容斥系数就是 \(-1\),否则为 \(0\)

注意还要考虑整个连通块不存在 \(d_i<y_i\) 的情况,这时等价于要求整棵树染色,在实现上可以先全部不管,最后再加上 \(1\)

总结一下,这个做法的关键在于容斥之后通过计数对象的转变(从集合到树上联通块再到点的贡献),容斥系数得到了极大的(?)简化,变成了便于计算(?)的形式。

更多细节可以看代码,其实很短。

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using LL = long long;
constexpr int MAXN = 2e5 + 5;
int n, mx[MAXN], smx[MAXN], out[MAXN], cnt_key[MAXN];
//子树内最大/次大,子树外最大,子树内关键点数 
vector<int> G[MAXN];
LL ans;
string S;
void dfs(int u, int fa) {cnt_key[u] += (S[u] == '1');for (int v : G[u]) if (v != fa) {dfs(v, u);cnt_key[u] += cnt_key[v];if (mx[v] + 1 > mx[u]) smx[u] = mx[u], mx[u] = mx[v] + 1;else smx[u] = max(smx[u], mx[v] + 1);}
}
void Get_out(int u, int fa) {if (S[u] == '1') ans += max(mx[u], out[u]);for (int v : G[u]) if (v != fa) {out[v] = max(out[u], mx[v] + 1 == mx[u] ? smx[u] : mx[u]) + 1;Get_out(v, u);}
}
void Get_ans(int u, int fa) {for (int v : G[u]) if (v != fa) Get_ans(v, u);if (S[u] == '1') {if (cnt_key[1] - cnt_key[u]) ans -= max(0, mx[u] - out[u]);//分讨情况:对于一个在连通块上不为根的关键点 u for (int v : G[u]) if (v != fa && cnt_key[v]) ans -= max(0, (out[v] - 1) - (mx[v] + 1));//分讨情况:对于一个在连通块上为根的关键点 u } else {//分讨情况:对于一个在连通块上的非关键点 G[u].emplace_back(0), mx[0] = out[u] - 1, cnt_key[0] = cnt_key[1] - cnt_key[u];//将原树上的父亲视为儿子 sort(G[u].begin(), G[u].end(), [&](int x, int y) { return mx[x] > mx[y]; });while (!G[u].empty() && !cnt_key[G[u].back()]) G[u].pop_back();int vismx = 0;//是否已经有比当前儿子子树最大距离更大的儿子被划分到 u 的“子树”内,如果有的话“子树”内最大距离是多少 for (int v : G[u]) if (v != fa) {if (vismx && cnt_key[v] && v != G[u].back()) ans -= max(0, vismx - (mx[v] + 1));vismx = max(vismx, mx[v] + 1);}}
}
int main() {IOS;cin >> n;for (int u, v, i = 1; i < n; ++i) cin >> u >> v, G[u].emplace_back(v), G[v].emplace_back(u);cin >> S; S = '#' + S;dfs(1, 0), Get_out(1, 0), Get_ans(1, 0);cout << ans + 1 << '\n';return 0;
}

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

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

相关文章

linux c web

您提到的“Linux C web”可能有多种含义,以下是几种可能的解释和相关建议:1. Linux 内核开发(C 语言) 如果您是在 Linux 内核开发中使用 C 语言,以下是一些常用命令和工具: 常用命令:gcc:编译 C 代码gcc -o my…

2025 年 钢丝网/钢骨架 塑料复合管厂家权威推荐榜/哪家好/有实力/可靠的/排名企业-江苏狼博管道制造有限公司

2025 年 钢丝网/钢骨架 塑料复合管厂家权威推荐榜/哪家好/有实力/可靠的/排名企业-江苏狼博管道制造有限公司** 2025 年 钢丝网/钢骨架 塑料复合管厂家权威推荐榜**钢骨架塑料复合管 钢丝网骨架塑料复合管 钢骨架聚乙…

CSS实现修改CheckBox样式

CSS实现修改CheckBox样式checkbox的代码:<div><input type="checkbox" id="custom-checkbox" class="custom-checkbox"><label for="custom-checkbox">&l…

人工智能之编程进阶 Python高级:第二章 面向对象

人工智能之编程进阶 Python高级:第二章 面向对象人工智能之编程进阶 Python高级 第二章 面向对象@目录人工智能之编程进阶 Python高级前言一、面向对象核心概念二、定义类和创建对象1. 基本语法2. __init__ 方法三、封…

OI vs Group Theory, Do You Guys Know?

TBD作者:ShaoJia,欢迎分享本文,转载时敬请注明原文来源链接。

2025年11月穿戴式吸奶器,电动吸奶器,百元吸奶器品牌测评排名,高性价比选购指南!

2025年11月穿戴式吸奶器、电动吸奶器、百元吸奶器品牌测评排名与高性价比选购指南在2025年11月,市面上的吸奶器产品琳琅满目,对于众多孕产妈妈来说,如何挑选到一款高性价比的吸奶器成为了一大难题。今天,我们就来重…

2025年11月百元吸奶器,静音吸奶器,便携吸奶器品牌测评排名,高性价比选购指南!

2025年11月百元吸奶器选购指南:聚焦卡乐怡等优质品牌在2025年11月,如果您正在为选择一款合适的吸奶器而烦恼,那么这篇测评排名及选购指南将为您提供有价值的参考。在众多吸奶器品牌中,卡乐怡品牌隶属的汕头市汇亨淇…

Q:R2R(Row-to-Row)映射 XML 是数据同步“源表字段→目标表字段” 的转换规则基础教程。

Q:R2R(Row-to-Row)映射 XML 是数据同步“源表字段→目标表字段” 的转换规则基础教程。Posted on 2025-11-18 20:26 三年三班王小朋 阅读(0) 评论(0) 收藏 举报R2R 映射 XML 语法速查表 一、核心节点层级(必记…

2025年11月免手扶吸奶器,穿戴式吸奶器,百元吸奶器品牌测评排名,清洁便捷优选!

2025 年 11 月免手扶吸奶器,穿戴式吸奶器,百元吸奶器品牌测评排名,清洁便捷优选!在母婴市场中,吸奶器是众多妈妈们的刚需产品。随着科技的发展,免手扶吸奶器、穿戴式吸奶器等新型产品不断涌现,为妈妈们带来了更…

【Azure Developer】解决在中国区 Microsoft Graph 命令Get-MgUserAuthenticationPhoneMethod 不可用的问题

问题描述 使用PowerShell Microsoft Graph 命令来获取用户认证的电话信息时,发现 Get-MgUserAuthenticationPhoneMethod 命令在中国区 Azure上不可用。报错:Get-MgUserAuthenticationPhoneMethod : Resource not fo…

基于Redis的滑动窗口限流-Golang实现

基于Redis实现滑动窗口限流,分析不使用lua时的并发问题常用限流算法 包括固定窗口、滑动窗口、令牌桶、漏桶 固定窗口: 将时间划分为固定长度的窗口(如 1 秒),窗口内维护请求计数,当请求数超过阈值时拒绝新请求。…

查看laya已经加载的资源

查看laya已经加载的资源Laya.Loader.loadedMap 不是Laya.loader, loadedMap是static的, 在Loader类中定义的.

ESP32 + LVGL 开发笔记(一):点亮屏幕

折腾了几天 lvgl,打算写一个简单的教程来记录一下。教程的最后会实现一下使用 lvgl 显示 lottie 动画的效果,见下图:环境介绍 硬件:esp32s3 n16r8核心板 1.47寸 ips lcd彩色屏幕(st7789)分辨率320 x 172,没有触屏…

聊聊deepseek对latex的辅助

聊聊deepseek对latex的辅助最近两天,用deepseek辅助latex写了一篇20页的反串讲文档,感觉结构清晰,且格式工整,一目了然。 很感慨的一点是,最开始的时候,是大学毕业论文时使用latex,当时就想着自己不用考虑work的…

【LVGL】图片部件

引言 图片部件(lv_img)图片部件相关 api 函数图片转换 LVGL 中要显示图片则需要 C 语言,或者 bin 的方式, 恰好 LVGL 官网提供了一个很好的在线工具:图像转换器 不过要注意的是选择自己当前的 LVGL 版本,下面是我…

linux c makefile

当然可以!在 Linux 系统中,makefile 是用于编译和构建项目的常用工具。它定义了项目的构建规则,帮助开发者自动化编译过程。一、什么是 Makefile? Makefile 是一个文本文件,它定义了如何编译和链接源代码。它告诉…

基于自适应遗传算法风光场景生成的电动汽车并网优化调度【IEEE33节点】(Matlab代码建立)

基于自适应遗传算法风光场景生成的电动汽车并网优化调度【IEEE33节点】(Matlab代码建立)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !importa…

10大 spring源码设计模式 (图解+秒懂+史上最全)

本文 的 原文 地址 原始的内容,请参考 本文 的 原文 地址 本文 的 原文 地址 尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、…

实用指南:《中国电力产业数字化》深度解析与前沿展望(下)——中国电力数字化转型路线图:SPARK 融合平台的设计与落地方案

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

High Frequency Active Auroral Research Program(HAARP)部分摘取

High Frequency Active Auroral Research Program(HAARP)部分摘取原网站:https://haarp.gi.alaska.edu/ 部分摘取:利用最近研发的强大且灵活的电离层加热器(如EISCAT加热器,以及最近建成的HAARP加热器)对高频无…