[Ynoi2004] rpmtdq

首先,不难发现如下性质:提任意点为根——记一个点的到子树重心的距离为 $d_i$,假设点 $i$ 和点 $j$ 处于根的不同子树中,那么显然:$(i,j)$ 路径上的权值和为 $d_i+d_j$;假若点 $i$ 和点 $j$ 处于根的同一颗子树中,又满足 $d_i+d_j$ 大于 $(i,j)$ 路径上的权值和。

现在,不妨看一个子问题:有一个长为 $n$ 的序列 $a$,每次给出一个区间 $[l,r]$,对于所有满足 $l \leq i < j \leq r$ 的 $(i,j)$ 求 $\min(a_i+a_j)$。

独立的这个问题可以用 $\text{RMQ}$ 做,但是,我们需要找到一种空间花销更小的做法。考虑进行转换,假设答案为 $(i_{ans},j_{ans})$,那么 $[i_{ans}+1,j_{ans}]$ 这个区间中的数一定是不小于 $i_{ans}$ 以及 $j_{ans}$ 的。记点 $y$ 前面第一个小于 $a_y$ 的点为 $a_x$,后边第一个不大于 $a_y$ 的点为 $a_z$,满足最终的答案必定是形如 $(x,y)$ 或 $(y,z)$ 的点对。然而不是所有这样的点对都可以来更新答案,因为点对需要满足 $l \leq i,j \leq r$。而恰恰同同时,会发现这样的限制条件形成一个二维偏序,可以 $O(n\log V)$ 的时间以及 $O(n)$ 的空间解决。此外,上述 $i$ 前面第一个小于 $a_i$ 的点可用单调栈解决。

回归原问题。我们进行点分治。对于每颗子树,维护其所有节点到子树重心的距离。根据一开始提到的性质,我们可以把子树中的节点按照编号大小记成一个序列,每个点的值就是 $d_i$,同时按照上述子问题中的单调栈方法对每个节点维护出一个区间。

会发现,这样维护共有 $n\log n$ 个区间。把他们放在一起排序,再利用扫描线算出每个询问的答案。

时间复杂度 $O(n\log^2n+q\log n)$,前者是对 $n\log n$ 个区间排序的复杂度,后者是二维偏序中扫描线的复杂度。

posted @ 2023-07-21 19:54  徐子洋  阅读(16)  评论(0)    收藏  举报  来源