看到换根果断lct啊,然而其实我板子还没有打熟,还不会维护子树信息,于是就挂掉了……
然而正解并不是lct。
其实好像很久很久以前将lca的时候好像讲到过一道换根的题,当时没有听懂。
直接说正解吧:
把dfs序搞出来用线段树维护。
用一个变量记录当前根节点,操作一直接改就行了。
然后是操作三:
分情况讨论,设当前根节点为root,询问的点为a。
如果root不在a的子树内,那么root不会影响a的子树,仍然输出1为根时的子树和就行了。
如果在子树内,
如图,如果要查询1的子树和,那么找到1与root这条链上靠近1的点,整体的和减去这个点的子树和就是了。(感性理解一下。)
那么这个点怎么求呢?只需要对于每个点把与他直接相连的儿子的dfs序塞到一个vector里,upper_bound然后-1就可以了。
操作二:
首先求出以1为根是a,b两点的lca。
与操作三类似,如果root不在lca的子树内,那么root不会影响lca,直接加就行。
如果在子树内,那么找a,b与root的lca中深度较大的那个。
之后就和操作三一样了。