dsu on tree
可以用来解决一些有下列性质的问题:
- 对子树询问
- 没有修改
算法
算法步骤如下:
- 遍历的一个节点
- 递归所有的轻儿子
- 递归重儿子
- 统计轻儿子对答案的影响
- 计算答案
- 如果自己是轻儿子,消除影响
1 | void add(int u, int father, int delta, int exc) |
时间复杂度
类似于树链剖分,可以证明对于一个点到根上的路径,轻边的边数是不会超过$logn$条的,因为经过一条轻边意味着子树大小至少乘$2$
那么根据算法,可以发现每个点需要消除影响的次数为$O(logn)$次,不需要消除影响的次数为$O(1)$次,那么总的时间复杂度为$O(nlogn)$