CF104160

发布时间 2023-12-08 10:11:07作者: Nityacke

CF104160

\(dis(T,a,b)\) 为在树 \(T\)\(a,b\) 之间的距离。

给定两棵各 \(n\) 个点的树 \(T_1,T_2\)\(q\) 次询问,每次给定两个数 \(a,b\),询问

\[\max_{i=1}dis(T_1,a,i)+dis(T_2,b,i) \]

\(1\le n\le 10^5,1\le q\le 5\times 10^5\)

我们对询问离线,在第一棵树上 dfs,枚举 \(a\) 计算询问的答案。

当我们 dfs 到 \(a\) 的时候,我们对于 \(T_2\) 上的每个点 \(i\),新建一个虚点 \(i'\)\(i\) 连接,边权为 \(dis(T_1,a,i)\),那么我们只需要在 \(T_2\) 上找距离 \(b\) 最远的点的距离即可。

由于直径的性质,这个点肯定是直径的一个端点,然后我们要维护 \(T_2\) 上直径端点,具体来说维护直径的 \((i,j)\)\(dis(i,i')\)\(dis(j,j')\),然后合并是简单的。

然后我们对 \(T_1\) 的 dfs 序建出线段树,每个位置维护 \(dis(T_1,a,i)\),那么每更换一个 \(a\) 就是 \(O(1)\) 次区间虚边边权整体加上/减去一个值,这个不改变这个区间的直径,直接做就好了。

采用 \(O(n\log n)-O(1)\ lca\),我们就可以在 \(O(n\log n+q)\) 的时间复杂度内解决问题。

口胡老哥,没有代码