题意:一棵树,有边权,求边权平均值最大且经过点数在 \([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
就过了…………………………