首页 > 其他分享 >点分树

点分树

时间:2023-02-17 14:23:02浏览次数:46  
标签:距离 fa 点分树 权值 维护 dis

一种用来解决一类与树的形态无关的问题。

首先需要知道点分治。然后点分树就是把点分治过程变成一棵重构树。一个点的儿子就是下一层分治中选择的重心。

容易发现点分树的深度是 \(O(\log n)\) 级别的,因此查询和修改时都可以暴力跳父亲然后用数据结构维护。

由于点分树的形态已经与原树毫无关系了,因此我们能够有的性质比较有限:

  • 两个点在树上的 LCA 在这两个点原树上的路径上,也即 \(dis(u,LCA)+dis(v,LCA)=dis(u,v)\)。

这个性质可以解决一类不关注树形态(比如路径之类的)的修改/查询问题。一般点分治的题加上修改或者强制在线之后就要上点分树了。

一般需要维护两个东西:自己子树内的信息和父亲关于自己子树内的信息,因为原树上这俩点没什么特别关系,直接维护会寄掉。

P6329

Done.

\(n\le 10^5\),要求支持修改一个点权值,求与一个点 \(dis\le k\) 的点的权值和。

点分树维护,每个点维护两个东西,一个 \(a_{i,d,0}\) 表示点分数上子树内的点到 \(i\) 点距离为 \(d\) 的权值和,另一个 \(a_{i,d,1}\) 表示与父亲距离为 \(d\) 的权值和。用树状数组维护前缀和。

树状数组开到 \(size_u+1\) 大小即可。

然后每次询问,从这个点开始跳,设跳到的点为 \(u\),父亲为 \(fa\)(当父亲是根的时候就不用跳了)。

设原来这个查询的点到 \(fa\) 的距离为 \(dis\)。

然后答案是初始这个点子树中到他的距离小于等于 \(d\) 的权值和,加上每一次跳,距离 \(fa\) 小于等于 \(k-dis\) 的权值和减 \(u\) 子树内距离 \(fa\) 小于等于 \(k\) 的权值和。

修改的时候直接暴力向根跳然后计算距离修改即可。

P2056

Done.

一棵树,每个点有个状态,初始全0。

要求支持切换一个点的状态(0/1切换),并且查询当前树上最远两个为0点的距离,两个点可以重复。若没有0点,输出-1。

点分树。维护三个可删除,支持查最大次大值的堆 \(a,b_{i},c_{i}\),\(c_i\) 中存 \(i\) 子树中到 \(fa_i\) 的距离,\(b_i\) 维护一个点每一棵子树中距离 \(i\) 最大的距离(也即每一棵子树仅有一个最大的距离在堆中),\(a\) 维护 \(b_i\) 的最大值与次大值之和。

然后一个可删除堆只需要两个 \(STL\) 堆,一个存放目前有的数,另一个存放目前待删除的数,每次如果两堆堆顶数相同就弹掉,就实现了可删除。手动封装下即可。缺点是常数大,不开 O2 时非常炸时间。

复杂度 \(O(n \log^2 n)\),对三个堆无脑直接模拟的话需要一个 \(5\) 以内的常数,开 \(O2\) 才能过。加点小优化不知道能不能裸着过。

标签:距离,fa,点分树,权值,维护,dis
From: https://www.cnblogs.com/infinities/p/17129960.html

相关文章

  • 点分树
    黄昏夕阳,铺一片余晖锦缎,远处炊烟袅袅,我们活在这美好温暖的人间。本文是基于辰星凌的博客QAQ大佬的博客的自己的一些“摘抄”和自己的一些想法点分治的核心思想在于依据......
  • 点分治与点分树
    点分治和点分树真的是各种意义上的好东西。不仅好玩,而且写完一看自己的代码5.几kb:“wc我今天搞了好多学习”。在做关于树的题时,我们会遇到一类题型:题目跟路径有关,你找到......
  • 动态点分治(点分树)
    点分树(动态点分治)点分治的核心思想在于依据重心划分子连通块,其良好的性质保证了最多只会分治logn层。有了这一特性,便可使用各种暴力计算答案。那么我们按照分治递归的......