P9665 [ICPC 2021 Macao R] Colorful Tree
题意
一棵树,维护:
- 增加一个叶子赋一个颜色
- 改一个节点的颜色
- 求目前树的两个不同颜色的点的最远距离
单 \(\log\),可以离线。
思路
首先先离线下来,这样可以提前求出最近公共祖先和距离什么的。对于最远距离考虑直径。那么涉及到这样子合并直径的东西可以考虑直径的一个性质
对于两个点集 \(S_1,S_2\),\(S_1\) 的直径是 \((u_1,v_1)\),\(S_2\) 是 \((u_2,v_2)\) 的话直径一定是 \(u_1,v_1,u_2,v_2\) 中的两点组成的。证明调整一下即可。
那么我们现在考虑这个不同颜色该如何做。考虑用线段树去维护颜色 \([l,r]\) 之间的不同色直径。那么按照分治,如果是全部在一个子区间就直接赋值,那么对于跨子区间。那么就等价是颜色在 \(\{x|c_x\in[l,m]\}\) 和 \(\{x|c_x\in [m+1,r]\}\) 的点集选直径。即维护 \([l,r]\) 的普通直径即可。
那么为了维护叶子的直径,我们对于每个颜色开一个动态开点线段树维护这个颜色的直径。
那么对于增加叶子,我们直接在那个颜色的线段树上将 \(u\) 表示不再空。对于改颜色我们将原来的颜色的位置设为空,在新的颜色的位置上设为有即可。
那么每次就是再更改一次所有颜色线段树的叶子结点即可。
使用 \(\mathcal{O}(n\log n)-\mathcal{O}(1)\) 求 LCA 即可单 \(\log\)。

浙公网安备 33010602011771号