其他分享
首页 > 其他分享> > 点分树学习笔记

点分树学习笔记

作者:互联网

关于点分树的一些理解

定义与性质

点分树,就是把点分治中的每一次的重心连起来,构成一棵树。
由于重心的性质,点分治最多有 \(\lg n\) 层, 所以点分树的树高最多是 \(\lg n\)

维护

一般维护两个值 \(s1\) 和 \(s2\) ,\(s1\) 表示这个点的子树对于这个点的贡献, \(s2\) 表示这个点的子树对于这个点的父亲的贡献。\(s2\) 用于对 \(s1\) 进行容斥

每次修改时要在点分树上不断跳父亲,修改点分树上父亲的信息。

每次查询时要在点分树上不断跳父亲,询问点分树上父亲的信息,一般要用到容斥。用 \(s2\) 容斥 \(s1\)

具体看了题就理解了。

用途

一般用于静态条件下点分治可解,但是强制在线或带修的题。

注意事项

点分树上的位置关系,距离关系,父子关系,祖孙关系,和原树上不同。

luogu6329震波

标签

点分治, 树状数组

思路

先考虑不带修的情况,那这就是道点分治裸题,但是这道题要求支持修改且强制在线。那么点分治就不能用了。

所以我们要用点分树。

对于每一个节点维护两棵树状数组 (\(vector\) 存) , \(s1\) 维护距离当前点距离为 \(k\) 的点的价值和, \(s2\) 维护距离当前点的点分树上的父亲距离为 \(k\) 的点的价值和。

对于修改操作,改成增加,然后在点分树上不断跳父亲,修改 \(s1\) 和 \(s2\) 。

对于查询操作,在点分树上不断跳父亲,设询问点和父亲的距离为 \(d\) , 那么对于每一层,把答案加上 \(s1[fa[i]].query(k - d) - s2[i].query(k - d)\) 用于去重,因为当前子树已经被计算过了。

维护两棵树状数组多麻烦啊,直接 \(s1[fa[i]].query(k - d) - s1[i].query(k - d - dis(i, fa[i]))\) 或者 \(s1[fa[i]].query(k - d) - s1[i].query(k - dis(i, x))\) 多方便,然而要注意 点分树上的位置关系,距离关系,父子关系,祖孙关系,和原树上不同。 所以这样做是错误的。

Code

[ZJOI2007]捉迷藏

标签:s2,s1,分治,笔记,点分,学习,点分树,query,树上
来源: https://www.cnblogs.com/youwike/p/15003779.html