题意简述
一棵树 $n$ 个点,点有颜色 $c_i$。
对于每个点,求出以其为根时,所有没有其他深度相同点的点的不同颜色个数。
$n\le 2\times 10^5$。
主要思路
不妨称在某个点为根时没有其他深度相同点的点为该点的合法点。
那么显然一个点的合法点在其到它最远点的路径上。最远点显然是直径端点之一,故只需对直径两端点提为根做一次。
那么此时一个点只需要关心它到根路径上的点了。
这条路径上哪些点是合法的呢?考虑一条从这条路径上的点开始的往下的路径,显然该点上方的路径长度个点都不合法。最后剩下的就是合法的。
dfs,用栈维护当前合法的点,用桶维护每种颜色的出现次数。
长链剖分,先往重儿子走(用轻儿子的最大深度弹栈),再往轻儿子走(用重儿子最大深度弹栈)。
注意到这样可以不必撤销——假设现在 dfs 到某点,走到某个儿子时若某个祖先被弹掉,该祖先在该儿子及其他儿子的子树内都应被弹掉。
但是有一个例外就是该点本身可能被弹掉后在别处仍合法,所以 dfs 一个儿子后要重新加回去。
总入栈次数 $O(n)$,故复杂度 $O(n)$。
参考代码
1 |
|