[复习]动态点分治

点分治,动态点分治,等等等各种分治。
因为我的智商经常欠费,导致我对于分治这个方面一窍不通。
但是动态点分治这个东西我又不是没有学过,只是过了这么久我什么都不会了。
所以还是重新理解一下吧。。。

首先,动态点分治需要构建出点分树,这个很好处理。
找重心是 O ( n ) ,每次重心分出来的每一棵子树的大小都不超过 O ( n / 2 )
所以总的复杂度是 O ( n l o g n ) 的。
点分树中的父子关系和原树中差距较大,但是并不影响我们对于信息的维护。
点分树的树高是 l o g 级别的,因此在点分树上暴力向上维护的复杂度是正确的。

因为点分树上的父子关系和原树的父子关系差距较大,
我们来考虑如何维护点分树上的信息。
按照题目来举例子,比如【BZOJ3730】震波
我们需要维护的东西是对于当前点距离不超过 x 的点。
我们看看在原树中这个东西怎么找:
我们确定一个根,转化为有根树。
对于每个点维护距离它不超过 x 的所有子树中的点,统计一下。
然后跳到父亲,统计一下距离父亲距离不超过 x 1 的所有子树中的点,
但是发现当前点中有一部分被重复算了,所以再减去距离当前点子树中距离不超过 x 1 的点。
然后继续跳到父亲的父亲……
因为点分树上的所有点的,都是原树中一棵子树的重心,
我们可以认为点分树上所有点的子树就是这个点在原树上的子树,只不过我们看的根不太一样而已。

既然这样,我们就可以向上面那样求解:
维护距离当前点不超过 x 的所有子树中的点。
跳到父亲,假设父亲和当前点的距离为 d ,找一下距离父亲不超过 d 的点。
然后减去距离当前点距离不超过 d 的所有点。
然后跳到父亲的父亲……

这样是对的原因也很简单:当前点一定是点分树上父亲的子树中的一个点。
那么我们在维护这个点的同时,只需要像上面所写的那样,再维护一下当前点对于父亲的贡献就好了。

猜你喜欢

转载自blog.csdn.net/qq_30974369/article/details/81046448