题意简述
给定一个 $n\le 10^5$ 个点带权的树,初始根为 $1$。支持三种操作:1 r
把根换成 $r$2 u v x
把 $LCA(u,v)$ 的子树整体加 $x$3 u
查询 $u$ 的子树点权和
操作数$\le 10^5$。每个点权 $\le 10^8$ 。
思路
如果没有 $1$ 操作,那 $2,3$ 操作显然就是一个板子。
但是现在有了 $1$ 操作。 那么我们就要考虑几个问题:
- 如何求 LCA
- 如何知道子树是哪一块 (对其进行求和或加值)
当然,无根树肯定是不好讨论的。我们先假定 $1$ 为根。 然后判断以 $r$ 为根的子树长什么样。
为了不混淆,设:
$LCA(u,v,r)$ 表示以 $r$ 为根,$u,v$ 的 $LCA$。
$SUB(u,r)$ 表示以 $r$ 为根,$u$ 的子树。
路径不需要重新定义,因为路径是唯一确定的,和根无关。
求LCA
假设我们要求 $LCA(u,v,r)$。
- 如果当前的根 $r$ 在 $u,v$ 的路径上,那么显然 $LCA(u,v,r)=r$。
- 否则,设 $L=LCA(u,v,1)$。 如果当前的根在 $SUB(L,1)$ 外,那么 $LCA(u,v,r)=L$,就不会有影响
- 再否则,$LCA(u,v,r)$ 就是 $u,v$ 路径上的某个点了。稍微想一下,这个点是 $LCA(u,r,1)$ 或者 $LCA(v,r,1)$ 中的一个。 再仔细想想,似乎是选深的那一个(以 $1$ 为根)。那么如果同样深怎么办呢?
继续想想,$LCA(u,r,1)$ 和 $LCA(v,r,1)$ 肯定一个是 $LCA(u,v,1)$ ,一个是 $LCA(u,v,r)$。如果深度相同,那就说明 $LCA(u,r,1)=LCA(v,r,1)=LCA(u,v,1)$ 。这个时候选哪个也无所谓了,反正都是对的。
求某个子树
假设我们要求 $SUB(u,r)$
- $u=r$。 最简单的情况,子树就是整棵树 (但是不能忘记特判!)
- $r$ 在 $SUB(u,1)$ 之外。 这也很显然,$SUB(u,r)=SUB(u,1)$。
- 关键问题就是 $r$ 在 $SUB(u,1)$ 之内的情况咋整。
我们画一张图:
很明显,此时 $SUB(u,r)$ 就等于整棵树中减去 $SUB(k,1)。(这张图有一个没画全的地方,就是 $u$ 上面可能还有别的点)
而 $k$ 的值,也就是 $r$ 在 $u$ 的哪个子树里面,这个可以用倍增求。
总结
我们发现,最后的操作,只有子树加减,和单点求和的操作。甚至不用写树链剖分。这个用 $DFS$ 序维护就能解决。
代码
1 |
|