重建计划 题解

题意:一棵树,有边权,求边权平均值最大且经过点数在 \([L,R]\) 的路径长度.

Solution

首先二分答案 \(x\),每条边权减去 \(x\) 后问题转为求最大路径长度,若答案 \(\ge0\) 则可行

1

边分治保平安。

  • 先转二叉树,这里有两种方法:一种是像线段树一样建,另一种是普通贪心的建,反正都可以
  • 然后边分治,对于重心边 \((u,v)\) 两头的子树,容易想到对于 \(u\) 处理出数组 \(f_i\) 表示路径长度为 \(i\) 的到 \(u\) 的最大路径长度,\(v\) 类似地处理出 \(g\)
  • 对于 \(g_i\),要求 \(\max_{j\in[L-i..R-i]}f_j\),单调队列即可

2

点分治:

  • 对于当前根 \(u\),依次处理子树,设当前处理到子树 \(v\)
  • 处理出 \(f_i\) 表示子树 \(v\) 前面的所有子树中 \(u\) 到其中一个点,深度为 \(i\) 的最大路径长度值,这个可以依次更新
  • BFS 当前子树 \(v\),设到当前节点 \(p\),深度为 \(dep\),我们要求 \(\max_{j\in[L-dep...R-dep]}f_j\)
  • 由于 BFS 节点的深度单调递增,查询区间单调递减,所以单调队列即可
  • 注意若要使复杂度正确,即遍历复杂度为 \(siz_u\),我们需要把儿子按他们子树深度最大值排序,这样 \(v\) 最多用到前一个子树深度最大值这么多个 \(f\),就正确了
  • 有个优化:预处理出点分树,这样就不用每次二分都求一遍重心

不知为何我的代码思路是对的但总是谜之 TLE……反正思路会了应该就行了

UPD:把 unordered_map 换成 map 就过了…………………………

posted @ 2024-04-20 23:15  Laijinyi  阅读(2)  评论(0编辑  收藏  举报