1 条题解
-
0
题意概述
有一棵 个节点的树,每个节点 有一个加油站的燃料量 (货车到达该节点时可以补充最多 单位燃料)。
货车从某个节点 出发时,油箱初始为空,会先加满 燃料。
每条边 有长度 (即消耗 燃料)。
货车从节点 能到达相邻节点 的条件是:离开 时的燃料量 。
货车可以经过任意多个节点,到达每个节点时可以补充燃料(但补充量不超过 ,且油箱无限大)。
问有多少个有序对 满足:从 出发,可以到达 。
问题分析
对于固定起点 ,我们需要知道它能到达哪些点 。
这相当于在树上做“燃料可达性”传播:- 从 出发,有初始燃料 。
- 走到相邻节点 需要消耗 ,到达后补充 燃料(最多补充 ,但实际补充量不能超过油箱剩余容量?题目说“可以在加油站补充不超过加油站燃料分量的燃料”,且油箱无限大,所以总是能补充 )。
- 因此,到达 后燃料量变为 ?
不对,因为如果到达前燃料足够,到达后剩余燃料是 ,然后再加 。
如果到达前燃料不足 ,则无法到达 。
所以条件:离开上一节点时的燃料 。
因此,从 出发的过程可以看作:当前在节点 ,拥有燃料 ,能走到相邻节点 当且仅当 ,走到 后燃料变为 。
转化模型
这类似于在树上做“能量传播”或“前缀和”问题。
设从 到 的路径为 ,边权 连接 和 。
出发时燃料 。
能走到 的条件:,到达后燃料 。
能走到 的条件:,即 ,到达后燃料 。
依此类推。归纳:能到达 的条件是: [ A_u + \sum_{i=1}^{t} (A_{x_i} - w_i) \ge 0 \quad \text{且} \quad \text{对于所有 } 1 \le j \le t,\ A_u + \sum_{i=1}^{j-1} (A_{x_i} - w_i) \ge w_j ] 第二个条件等价于:路径上任意前缀的“净收益”足够支付下一段边的费用。
进一步简化
定义边权 ,节点权 。
从 出发到达 的路径上,设路径序列为 ,边 权为 。
出发时燃料 。
到达 前需满足 ,到达后 。
能到 需 ,即 。更直观:令 ?
对于固定起点 ,到达某节点 的条件是:从 到 的路径上,任意前缀的“累积燃料”不低于下一段边的需求。这类似于“路径最小值”问题:定义从 到 路径上的一个函数:
- 在起点 处值为 。
- 经过边 权 时,值减去 (消耗),然后加上 (补充)。
于是到达节点 的条件是:从 到 路径上的最小前缀值(在每次加 之前)必须 (实际上应该 下一条边的权,但这样不好统一)。
另一种视角:转换为“差值”模型
令每条边的新权值为 。
含义:从 出发到 ,消耗 后,在 补充 ,所以从 到 的净燃料变化是 ,但这不是从 出发时的燃料,因为出发时还有 补充?等等。更准确:设 表示从 出发时的燃料量,出发时先加 ,所以 。
走到 (相邻)需要满足 ,到达 后剩余 ,再加 ,所以到达 时的燃料量 。
所以转移为 ,前提是 。因此,如果把 看作边 的“增益”,那么 ,但前提是 。
这个前提条件依赖于边的原始权值,不能完全吸收到增益里。
关键观察
对于树上的路径 ,设路径为 。
定义 $P_j = \sum_{i=0}^{j} a_{x_i} - \sum_{i=1}^{j} w_{i}$,其中 是边 的权。
那么到达 的条件是:对于所有 ,有 。等价于:对于路径上的任意位置 ,有 。
这很难直接处理所有起点。
经典技巧:点分治
因为 ,我们需要 或类似复杂度。
点分治是处理树上路径统计问题的常用方法。对于分治中心 ,考虑所有经过 的路径 ( 和 在不同子树中)。
我们需要统计满足条件的 数量。对于从 到某节点 的路径( 作为起点),可以计算:
- 从 出发到达 所需的最小初始燃料量 (即保证从 到 路径上不会燃料耗尽的最小初始值)。
- 到达 后剩余的燃料量 (如果从 出发时有足够燃料的话)。
类似地,如果 是起点, 是途径点,也可以计算从 到 的需求和剩余。
计算 need 和 rem
对于从 到 的路径( 是起点): 设路径为 ,边权 在 。 定义:
- 初始燃料 (出发时补充)。
- 到 需 ,到达后 。
- 到 需 ,即 。
可以递推计算 :
设 是从 出发到达 所需的最小初始燃料量(即在 出发时的燃料量必须至少为 才能到达 )。
递推:对于边 权 ,从 到 ,如果已知从 到 所需的最小初始燃料 ,以及到达 后的剩余燃料 (假设初始燃料正好为 ),那么:- 要能到 ,必须有 。
- 如果 ,那么到达 后剩余 ,且 (因为初始燃料已经够)。
- 如果 ,则需要增加初始燃料,使得 ,于是 ,且 (因为补足后到达 时剩余 )。
这样可以在 内计算。
点分治步骤
-
选择重心 。
-
对于 的每个子树,计算子树内每个节点 (相对于 作为起点)的 。
-
对于 作为起点的情况,需要统计有多少对 满足 在某个子树, 在另一个子树,且从 出发能到 经过 。
这需要交换 和 的角色,即从 出发到 需要满足一定条件,然后从 到 也要满足条件。 -
具体地,对于有序对 ,路径 。
设从 到 的需求为 ,剩余为 。
设从 到 的需求为 ,剩余为 。
条件:- 从 出发时燃料为 (因为出发时加满),所以必须 ,并且到达 后燃料变为 (如果 ,则多余部分保留)。
- 从 到 需要初始燃料至少 ,而到达 时的燃料为 ,必须 。
所以条件为: [ a_u \ge need_{u\to c} \quad \text{且} \quad rem_{u\to c} + (a_u - need_{u\to c}) \ge need_{c\to v} ] 简化:$a_u + rem_{u\to c} - need_{u\to c} \ge need_{c\to v}$。
定义 ,则条件为 且 。
-
因此,对于每个子树,我们可以收集所有节点的 ,然后对于不同的子树,统计满足 (其中 )且 (这个条件对于 自身是自动满足的,因为 是根据 算出来的吗?需要检查)。
实际上 的计算与 有关,但 可能大于 吗?可能,如果 到 路径上需求很大, 可能不够,那么 根本到不了 ,所以这样的 不会出现在统计中。
所以我们在计算 时,如果发现某一步需求大于 ,则 无法到达 ,直接忽略。
-
因此,算法为:
- 对每个子树,收集能到达 的节点 ,记录 。
- 对于另一子树的节点 (从 能到达 ),记录 。
- 统计有多少对 满足 。
这可以用排序+双指针或树状数组完成。
-
还要考虑 或 的情况,以及 和 在同一个子树的情况(这些会在递归子问题时处理)。
复杂度
点分治 ,每次处理需要 排序( 为子树大小),总复杂度 。
总结
本题是树上的路径可达性计数问题,通过点分治将路径分为两半,并利用 和 的性质,将条件转化为值比较,从而用排序或树状数组统计。
关键点:- 将燃料约束转化为路径上的前缀条件。
- 使用点分治处理所有路径。
- 计算从一点到另一点的燃料需求和剩余量。
- 将条件简化为值比较,高效统计对数。
- 1
信息
- ID
- 5739
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者