1 条题解
-
0
好的,这是该题目的详细文字题解。
NOI 2014《购票》题解
问题抽象
我们有一棵以 为根、 个节点的树,每个节点 (除根外)有:
- 父亲
- 到父亲的距离
- 票价参数
- 距离限制
从 到 可以分段购票:每次选择 的一个祖先 ,花费 ,但要求 。求每个 到 的最小总花费。
1. 基础定义与 DP 方程
设 表示 到根 的距离(边权和,前缀和),可以通过一次 DFS 求出。
设 表示从 到 的最小总花费。对于 :
$$dp_u = \min_{a \in \text{anc}(u),\ d_u - d_a \le l_u} \big\{ dp_a + (d_u - d_a) \cdot p_u + q_u \big\} $$其中 是 的祖先集合(含 自身)。
2. 公式变形
把常数部分分离:
$$dp_u = \min_{a} \big\{ (dp_a - d_a \cdot p_u) \big\} + d_u \cdot p_u + q_u $$对于固定的 ,我们要在满足 的祖先 中,最小化:
记 ,,那么 。
这是一个关于 的线性函数形式:在二维平面上有若干点 ,要找一条斜率 的直线 穿过某点时的截距 最小,即 最小。
3. 几何转化:凸壳维护
在平面上,如果我们有一组点 ,那么使 最小的点,一定在这些点构成的下凸壳上。
下凸壳性质:按 排序后,相邻点连线斜率递增。
查询:给定斜率 ,在下凸壳上找到第一个斜率大于 的线段左端点,该点即为最优决策点(可二分查找)。
4. 距离限制的处理
对于 ,合法的 需满足 。
因为 随 靠近根而减小,所以这相当于在祖先链上取一个后缀。因此我们需要在 到根的路径上,对 在某个值以上的祖先点维护凸壳,并支持查询。
5. 特殊情况分析
题中 参数提示了部分分做法:
-
或 : 极大,无距离限制。此时只需在整条祖先链的凸壳上查询。因为 (链)或任意树但无限制,可以用栈维护凸壳, 或 (若 单调)解决。
-
或 :树是一条链,。祖先链就是 。此时 单调递增,可以用单调队列维护凸壳,并在队列上二分找到第一个 的位置(即满足距离限制的最远祖先),然后在该段凸壳中二分查询。复杂度 。
-
:一般情况,树形态任意,有距离限制。
6. 一般情况解法:树分治
对于树上任意路径问题,点分治是常用方法。
核心思想:
考虑当前分治中心 ,对于 子树中的节点 ,它的路径可以分为两段: 和 。
如果我们在 处购票,则可以从 跳到某个祖先 ,这样 的花费为 ,其中 。
分治步骤:
- 找重心 。
- 递归处理 的各个子树(不经过 的路径)。
- 处理经过 的路径:
- 收集 子树中所有节点 。
- 对每个 ,计算它到 的距离 。
- 对于 到根 的祖先链,按 从小到大加入凸壳(因为 向根递减,但加入顺序反过来)。
- 对每个 ,找到最小的 满足 (即最近的可跳祖先),在凸壳中查询斜率 的最小截距,来更新 。
- 继续递归 的子树。
关键细节:
- 凸壳按 排序(递增),但祖先链上 递减,所以要从根向 加入凸壳。
- 查询时,需要在凸壳中二分找到斜率 的最优点。
- 由于 限制,可能只需凸壳的一段,因此还需二分左边界。
7. 复杂度分析
每次分治,凸壳构建 ( 为当前层点数),查询 ,总复杂度 。
如果用可持久化凸壳(主席树)可以做到 ,但实现复杂。
8. 总结步骤
- DFS 预处理 。
- 初始化 。
- 对整树进行点分治:
- 找重心。
- 递归处理子树。
- 构建祖先链凸壳。
- 用祖先凸壳更新子树节点 DP 值。
- 输出 。
9. 注意事项
- 距离和费用可能很大,用
long long存储。 - 二分斜率比较时注意避免浮点数误差,用交叉乘法比较。
- 凸壳维护时注意弹栈条件。
- 树分治中注意标记已访问的重心,避免重复。
这种“DP + 斜率优化 + 树分治”的组合,是解决树上路径限制优化问题的经典模式。
- 1
信息
- ID
- 5707
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者