动态树的一些总结。

动态树这种东西,别人都已经写了几十遍了,我都还以为不会考。感觉自己就是个逗啊。。。


首先顾名思义,动态树的用处就是让树动起来(有时候也不用动)。


先讲几个动态树的概念:

动态树由两个东西组成:

一个是原图

一个是若干棵splay树(用来记录重链,具体后面讲),我们称其为辅佐树。


单颗splay记录的东西

他其实记录的就是我这一条链的有关信息。

左右儿子的确定是由原树中的深度确定的。也就是说,假如i是j的父亲,在splay中i相对j而言就是左儿子。


动态树的有关操作

动态树的核心操作是access(x)

其意义为在原图中,将x到root的路径标记为一条重链,并对辅佐树进行一定的修改。

过程?

 设x为当前节点,nxt为上一个节点(也就是说x由nxt跳来)

先讲x splay到x所属的链的根,那么x的右儿子现在就不属于x的重链了,我们将他分离出去(具体实现见代码)

然后将nxt赋为x的右儿子.

nxt = x,x = x重链的父亲。

然后一直迭代知道将x->root赋为一条重链。

代码十分简单。


处理完access操作之后,动态树也就变得十分简单了。

以下是几个常用的操作:

最常用的就是evert(x)  (将x作为原图的根):

Access(x)之后splay(x),并给x打一个翻转标记即可。(不用讲了吧。。)

link(x,y)  (x,y原图中在不同树中)

evert(x),evert(y),后splay(y),Par[y] = x,再Access(y)就可以了。

cut(x,y) (x,y原图中属于相邻两个节点)

evert(x),Access(y),Splay(y),将y与其左儿子分离开就好了。

对于询问操作(x,y):

我们先Access(x),可以发现x到root上的节点都在同一条链上了。

我们在Access(y)的过程中:

注意到w跳到所属重链的父亲---〉(w = par[w])时,

若此时,par[w] = 0,即w与根同属一条重链

那么w就是x,y的LCA了!!(显然)

那么此时nxt所属的重链就是w->y的链的信息

w->R_son就是w->x的链的信息。

然后就没然后了。。


动态树说起来好像好简单的样子(实际裸题也十分简单)

动态树的一些总结。_第1张图片

今年NOI2014 day1T2就呵呵了。。。


习题集:

spoj OTOCI

spoj DYNALCA,DYNACON1(一直到现在都没过。。)

spoj QTREE1 -> 4

NOI2014 魔幻森林

BJOI2010次小生成树

其实这些都是比较基础的啦。。。

之后要搞的东东->

(能对子树进行操作的动态树,那个叫啥来着。。)

后缀自动机。

AC自动机的DP以及各种各样的扩展。

DP优化。

平面几何。。

叼炸天的数论。。。

弱菜哭倒在地。。。

                           

你可能感兴趣的:(动态树的一些总结。)