引入
现在我们需要一个数据结构满足支持以下的操作:
- 两个节点连接(保证不出现环)
- 两个节点断开
- 求任意两个节点之间的区间和
这样是不是很像树链剖分? 但是因为是动态的所以我们采用动态树来进行维护。
样例
现在给出一个样例,我们一下的解释都以当前样例为模板
我们有三个节点1 2 3 4,现在他们是连接在一起的如下图
为什么有一个虚线呢,这里我们用虚线表示假装连接在了一起(这里下文会讲到)
操作
首先我们因为需要维护的是一棵树,我们利用树链剖分的思路,我们将当前树分为许多条链分别用Splay进行维护,这样我们就用上图的表示1->2是类似于轻边的东西,1->3是类似于重边的东西,但是这都是临时的
那么我们因为需要一条链那么我们需要以下的操作
操作一(一切的基础)
我们利用Access(u)表示从当前根到u变为重边,同时让这条链独立出来,那么我们可以通过Access(2)得到以下的图
这样1->2就成为了一条链,同时将3孤立出去了
操作二(Splay=神奇的相对位置)
我们通过一个Splay来维护每一条链(的深度),在每一条链成为一个Splay进行旋转的时候,位置并不是不改变的对于上图我们有三个Splay
1、1->2
2、4
3、3
这样的三棵树我们在旋转Splay的同时每一个Splay的根的父亲表示的是当前链的最顶端的父亲(也就是深度最浅的那个节点),并不是Splay的root节点的父亲,这样我们保存的就是相对位置就像我们使用Splay(2)上面的图就会转成
通过观察可以发现其实相对的位置其实是没有改变的。
操作三(make_root=让整个树换个方向吧)
其实我们的动态树没有动他会感到寂寞
我们可以发现对于任意一个节点都可以成为新的根,同时其他的都可以跟着翻转就行了,那么我们首先想要成为Boss我们第一步就是进入和根连接的中心链中,这样