1 条题解
-
0
题意重述
我们有一棵 个节点的树,每个节点权值 。
要找一条简单路径,设路径上节点权值依次为 ,满足:- 任意前缀和 。
- 总和 。
- 定义 NP 值 = 前缀和的最大值。
求最大可能的 NP 值,若不存在这样的路径输出 。
第一步:转化为括号序列问题
令 对应左括号
((权值 ), 对应右括号)(权值 )。条件 1 和 2 等价于:序列是合法括号序列。
条件 3:NP 值 = 前缀和的最大值,即括号序列的最大嵌套深度。例如:
- 序列
(()())权值:,前缀和:,NP = 2。 - 序列
()()权值:,前缀和:,NP = 1。
问题变为:
在树上找一条简单路径,使得路径上的权值序列是合法括号序列,且最大嵌套深度最大。
第二步:思考路径性质
假设路径 合法,设路径长度为 (节点数)。
因为总和 ,所以 为偶数,且其中有 个 和 个 。
最大嵌套深度 ,取值范围 。我们要最大化这个值。
第三步:点分治框架
树上路径统计问题常用点分治。
考虑经过分治中心 的路径 ( 在不同子树中)。对路径 ( 在子树中),记录以下信息:
- : 到 的权值和(从 出发)。
- : 到 路径上前缀和的最小值(从 出发)。
- : 到 路径上前缀和的最大值(从 出发)。
注意:这里的前缀和是从 开始计算的,即第一个权值是 的权值(如果 在路径中间,我们分两段处理)。
第四步:路径合并条件
对于 和 两段( 在不同子树),拼接成 路径时:
设 的 ,,。
的 ,,。拼接后路径的权值序列为 反转再接 。
但直接反转 不方便,我们换种方式:考虑路径 的权值序列,从 开始:
- 先走 ,设这段的权值序列为 (长度 )。
- 再走 ,序列为 (长度 )。
的总权值和 (从 到 的和)。
的总权值和 (从 到 的和,这里 )。由于整条路径总和 ,所以 。
更简单的处理方式
换一种拼接方法:
将 的路径反转,变成从 到 的路径,此时权值和取反,且前缀和最值会变化。设 的 ,,。
那么从 到 的权值和 ,并且从 到 的前缀和最值不容易直接由 得到,但可以通过原始序列反转推导。不过这样复杂,我们采用更常用技巧:
在点分治时,对中心 ,我们分别处理 的每个子树,计算 到子树中节点 的信息 。对于拼接 ,路径权值序列 = 。
我们枚举 和 ,要求:- (总权值和 )。
- ( 段自身合法)。
- ( 后再走 的前缀最小非负)。
第五步:计算 NP 值
对于满足条件的 ,整条路径的前缀和最大值出现在:
- 可能在 段:。
- 可能在 段:(因为 贡献了 ,再加 的前缀和)。
所以 NP = 。
我们要最大化这个值。
第六步:点分治实现细节
- 找重心:标准点分治。
- 处理子树:对每个子树 DFS,计算从中心 到节点 的 。
- 初始 (如果 是起点,其实我们算 时起点是 , 是 到 的权值和)。
- 是路径 上以 为起点的前缀和最小值。
- 是前缀和最大值。
- 合并信息:
维护一个数组或哈希表 ,记录 的所有路径中,对应的 信息。
因为我们要匹配 互为相反数的路径,且满足 和 。
对于当前子树的每个路径 ,查询 中满足 且 的条目,计算 NP 值更新答案。 - 更新信息:将当前子树的路径信息加入 ,用于与后面子树合并。
第七步:特例:单段路径
除了拼接两段,也要考虑单段路径( 到某点 自身就是合法括号序列且总和 )。
此时 且 ,NP = 。
第八步:复杂度
点分治 ,每层 DFS 子树 ,合并时利用 范围 用数组存, 处理每层。
总复杂度 。
第九步:样例验证
样例:
5 0 -1 1 1 1 -1 2 1 2 -1权值:。
树结构: 1 是根,孩子 2,3。
2 的孩子 4,5。合法括号序列路径:例如 权值: 不合法(总和不为 0)。
要找总和为 0 且前缀和非负的路径。试 : 总和 1,不符合。
实际上可以找到一条路径 :权值 不合法。
最终答案 可能来自路径 ?但简单路径不能重复点。通过点分治可找出最大 NP=2 的路径。
第十步:总结
本题核心步骤:
- 将问题转化为树上找合法括号序列路径,最大化最大嵌套深度。
- 使用点分治处理经过某点的路径。
- 维护 信息,合并时检查合法性条件并更新 NP 值。
- 注意单段路径也要考虑。
- 1
信息
- ID
- 5941
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者