zoukankan      html  css  js  c++  java
  • Link-Cut Tree学习笔记

    Link-Cut Tree学习笔记

    自己好菜啊,省选之前啥算法都不会,考试把一个(nlog n)的LCT题硬是写了个(nlog^2{n}).但是跑过去就对了.

    所以现在要来重新学习一下( ext{Link-Cut Tree}).

    定义

    一个资磁动态加边,删边,维护信息的数据结构,叫做(LCT).

    前置知识

    Splay

    Orz yyb

    实链剖分

    讲道理我真的不知道实链剖分改叫什么名字.

    你考虑对于原来树上面的非叶子节点,指定一个实儿子,其他的都是虚儿子.

    与重链剖分和长链剖分不同,实链剖分需要比较快捷的维护,这个时候我们就需要用到( ext{splay}).

    性质

    1. 每一个( ext{splay})维护的是原树上的一条实链,而且中序遍历按照深度排序.
    2. 每一个节点只会出现在一个( ext{splay})里面.
    3. 实边的儿子会给儿子节点,虚边的儿子只是指向父亲.

    操作

    前置操作

    你需要资磁( exttt{pushup,pushdown,reverse,rotate})的操作,这里不再赘述,和( ext{splay})维护数列一样.

    access操作

    首先是一个贼牛逼的操作,考虑我们现在要把一个点到根节点路径上的所有边都变成实链,也就是让路径上的点在一个( ext{splay})里面,代码如下:

    void access(int x)
    {
        for(int y=0;x;y=x,x=t[x].ff)
        {	
            splay(x);t[x].ch[1]=y;pushup(x);
        }
    }
    

    我们考虑如何修改实链,首先你需要把(x)变成(splay)的根,以维护第一个性质,不然你改了右儿子但是这个右儿子实际上应该是在父亲的之类的.

    然后因为(y)的深度比(x)大,所以要放在右儿子位置.

    最后改了儿子,然后(pushup)一下.

    findroot操作

    int findroot(int x)
    {
    	access(x);splay(x);
    	while(t[x].ch[0])x=t[x].ch[0];
    	return x;
    }
    

    考虑找到它对应的根,等于是我们把他到根的路径(access)出来,然后把他变成(splay)的顶端,接着考虑一直往左儿子走,这样子走就是不断把深度变大.

    makeroot操作

    void makeroot(int x){access(x);splay(x);reverse(x);}
    

    这个时候我们要把(x)变成根节点,然后重新定义深度.考虑先把(x)节点(access)上去然后(splay),此时在(x)左边的就是原本深度比(x)大的,右边因为(access)上去了,所以没有右儿子.考虑把儿子(reverse)一下,这个时候就满足了我们的要求了.

    split操作

    
    

    我们需要资磁把两个节点的路径抠出来,那么我们可以把一个变成根节点,另一个(access+splay)即可.

    Link操作

    直接一个(makeroot)然后连成另一个的虚儿子即可.

    Cut操作

    首先可以把两个的路径(split)出来,此时如果两个点有直接连边的话,显然是(y)的左儿子就是(x),这个时候我们直接断掉对应关系即可.

    Link+Cut代码

    void Link(int x,int y){makeroot(x);t[x].ff=y;}
    void Cut(int x,int y)
    {
    	split(x,y);
    	t[y].ch[0]=t[x].ff=0;
    }
    

    这就是(LCT)的基本操作.

    维护子树信息

    (lct)还可以维护子树信息,这里的子树可以是实子树,也可以是虚子树.

    • 如果是维护实子树信息,你需要多写一个(pushup),(splay)里面多存一个变量表示子树的信息.

    • 如果是维护虚子树信息,你需要在(access)的时候加上原来的右子树,即把原来的边变成虚边然后加入贡献,新的改成实边的删除贡献.

    未完待续

    题目会慢慢补的.确信

  • 相关阅读:
    Maven创建项目: Failed to execute goal org.apache.maven.plugin( mvn archetype:create)
    maven仓库--私服(Nexus的配置使用)
    maven仓库--私服(Nexus的配置使用)
    maven仓库--私服(Nexus的配置使用)
    maven中snapshot快照库和release发布库的区别和作用
    maven中snapshot快照库和release发布库的区别和作用
    maven中snapshot快照库和release发布库的区别和作用
    Bugzilla使用手册及解决方案
    jQuery常见的几个文档处理方式
    正则表达式实现对多个表格的某一指定字段的样式添加
  • 原文地址:https://www.cnblogs.com/fexuile/p/13035190.html
Copyright © 2011-2022 走看看