0%

树上链领域修改问题

还没写完,估计是个论文级别的大坑

问题引入

NOI2021 中的《轻重边》,一种比较经典的解法是将操作视为点染色,然后处理相邻点颜色相同的数量得到答案。但还有一种真正的树链剖分做法,这种做法能够体现树链剖分的本质——将树划分成 $\log n$ 条链,依次处理它们。

这一类题本质上都是树上邻域修改问题,即给定一条链,修改这条链的邻域。

单点邻域修改

条件:操作存在结合律。

给定一个点,修改其树上邻域。

这个是比较好做的,分两种情况讨论,操作是否存在逆元(且逆元容易求解)。

操作存在逆元

将一个点的操作视为两个部分,自身+父亲,对一个点的邻域操作时,在自身上打一个标记,暴力修改自己父亲的值,如果操作存在交换律则没有问题,如果不存在,则需要先得到父亲的真实值,然后操作后再放一个父亲的父亲标记的逆元。

共需进行 $O(n)$ 次操作和求解逆元。

操作不存在逆元

如果操作只有结合律,那么会比较麻烦,如果是邻域赋值这类和之前的值无关的操作,可以记录一下每个点操作时间戳,清空一下树上标记,还是有救的。

如果和之前的值有关,并且查询只在最后做,那么可以开线段树记录一下

操作不存在结合律

没救了,暴力吧。

单点 $k$ 阶邻域修改

树剖的优势

首先处理的操作必须具备结合律

首先处理在链上的情况是比较容易的,因为邻域只涉及额外 $O(1)$ 个点,我们需要将这个优势拿到树上去。

考虑每次处理的 $\log$ 条重链,对于每条重链,它只会在 $top_u$ 处对其它,或者受到其它重链的影响。不妨将对一个点的修改放到两个地方,它自己和它父亲