爱悠闲 > 相关文章 >

link-cut tree

link-cut tree
, 有益身心健康 :链剖分讲解版 (ps:这个博主很爷但是很奇怪,大家要小心) splay的文章我就不引用了,大家随便百度看书都有 说白了,LCT就是用splay实现动态的链剖分 我们会发现,链剖分是用的线段(至少上面那个是) 可是动态就是因为会动而讨厌 嗯,如果我们把用线段维护的东西改成用伸展,以深度为顺序构建splay 听起来可行的样子 多么和谐! 可是具体怎么实现呢? 膜拜一下树链剖分,我们学着用splay维护每次访问的点到它所在树根的链 我们定义 u 的儿子中访问时间最后的点为
动态(Link-Cut Tree)学习小结
动态LCT)支持合并分离等操作,是一棵可以动的~ 类似于链剖分(建议先学完链剖分,再学LCT)。 只不过链剖分的轻重边是根据子树大小而决定的,这棵只能是静态的。 而LCT中的“轻重边”是根据最后一次操作决定的,最后一次处理了x这个点,那么从x到根的路径就是重链(每个父亲只与一个儿子的连边为重边)。 用splay来维护每一条重链,以点的深度为关键字,即splay中的每个点左儿子深度都比他小,右儿子的深度都比他大(若只有一个点,那么这个点单独是一棵splay)。 先来定义一些量
[BZOJ 3669][NOI 2014]魔法森林(Link-Cut Tree)
的本题lct版本代码和bin神的lct模板,自己yy乱弄了下过了这个题。 下面是我的思路,如有错误请不吝指教。 first of all,我们要构造下这题的LCT,在这题中,图有n个点m条边,于是lct里,下标在[1,n]的结点都是图中的点,下标在(n,m+n]中的结点都是图中的边,只有边对应的结点有权值,这个权值就是对应的边的b值。 然后我们用类似kruscal的方法,将每个边按照关键字a值升序排序,然后搞个并查集,维护图的连通性。 接着,我们像搞最小生成一样,按a值从小到大不断地加边,维护并查
LCT link-cut tree Hdu 5002 Tree 2014鞍山网络赛
之前一直听说link-cut感觉非常神奇,一直不敢学习,认为太难了,但确实是比较难。 但是好奇心还是比较强的,但是网上的信息不多,学习比较麻烦。这里不仅写个解题报告,也写个lct的讲解 由于这个暑假集训的时候我看完链剖分,splay 链剖分会线段以后就容易了,网上有很多写的好的博客 splay可以看《伸展的基本操作与应用》 然后就是lct了,《QTREE解法的一些研究》把基本的操作和证明都讲的很详细。 但是呢,我还是没有很明白具体的操作。后来看到一个解题报告,代码写的很好,于是明白
BZOJ 3732 Network Link-Cut-Tree (我是认真的!!
题目大意:给定一个n个点m条边的无向连通图,k次询问两点之间所有路径中最长边的最小值 LCT的裸题!首先维护一个动态的最小生成,然后每次加入边时删除两点间路径上权值最大的边!最后询问时直接求x到y链上的最大权值即可!水爆了!! 。。。好吧开玩笑的 真正的题解见http://blog.csdn.net/popoqqq/article/details/39755703 我只是闲得无聊水一发LCT罢了0.0 TLE了好久。。。因为有边权为0的边我没更新。。。 #include<cstdio
BZOJ 2631 tree 动态(Link-Cut-Tree)
题目大意:维护一种树形数据结构,支持以下操作: 1.树上两点之间的点权值+k。 2.删除一条边,增加一条边,保证加边之后还是一棵树。 3.树上两点之间点权值*k。 4.询问树上两点时间点的权值和。 思路:利用动态维护这棵lct的裸题。如果不会下传标记的,先去做BZOJ1798,也是这样的标记,只不过在线段树上做,比这个要简单许多。 这个也是我的LCT的第一题,理解起来十分困难啊。。。 CODE: #include <cstdio> #include <cstring> #include
BZOJ 3282 Tree Link-Cut-Tree 动态
题目大意:维护一种动态树形数据结构,支持: 1.求树上两点之间的点的异或和。 2.连接两点(不保证不连通) 3.删除连点之间的边(不保证两点联通) 4.将一个点的点权改成一个值 思路:还是LCT,思路也比较裸。主要是它各种不保证,所以要多加判断。 CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 300010 using namespace std
BZOJ 2759 一个动态好题 Link-Cut-Tree+扩展欧几里得
题目大意:给定n个形如xi=ki*x_pi+bi mod p的同余方程组 支持修改操作和求解操作 确实好题 感谢此题作者 顺便吐槽一下作者的Splay不加空节点太蛋疼了0.0 将每个点i的父亲设为pi 我们将会得到一座基环树林 将环上的一条边拆掉,在边的起始节点新开个域special_father记录这条边(P.S:好浪费 但是没办法) 于是我们得到了一座森林 显然可以用LCT来维护 每个节点的权值是个二元组(k,b),记录每个点关于答案的线性关系,合并时左侧代入右侧中 查询时将root
Link-Cut Tree
Link-Cut Tree是一种解决动态问题的数据结构。 动态问题,大概也就是要动态维护树的路径上的一些信息之类的。   定义操作节点Acs,无实义,但对的形态会造成影响。 其基本思想是动态链剖分,每个节点向其最后Acs的子树引一条P边,连续的P边组成P链,这样整棵树便被剖成了许多P链。 对于每条P链,根据深度用Splay维护之,并在Splay的根记录其最浅节点所连点,即为虚边。至此,整棵树成了很多坨Splay和一些虚边。   <1>链剖分 便于快速和维护路径信息。   <2
BZOJ 3786 星系探索 DFS序+Splay
题目大意:给定一棵有根,提供下列操作: 1.询问某个点到根路径上的点权和 2.修改某个点的父亲,保证修改之后仍然是一棵树 3.将某个点所在子树的所有点权加上一个值 子树修改,LCT明显是搞不了了,在想究竟会不会有人去写自适应Top-Tree…… 首先我们DFS搞出这棵的入栈出栈序 然后入栈为正出栈为负 那么一个点到根的路径上的点权和就是从根节点的入栈位置到这个点的入栈位置的和 子树修改就记录某段序列中有多少入栈和多少出栈,然后根据这个对这棵子树所在序列修改即可 那么换父亲操作呢?显然可以用
BZOJ 3786 星系探索 Splay维护树的入栈出栈序
题目大意:给出一棵树,要求有以下这些操作:1.求出一个节点到根的点权和。2.将一个节点的父亲改变。3.将一个子树中的每一个节点都加上一个权值。 思路:LCT就不用想了,因为有子树操作。然后就是一个很神奇的东西了,就是Splay维护树的入栈出栈序。这个玩应是做了这个题之后才知道的。但是感觉真的很dio。 首先,我们先按照题意,将建出来。然后从根开始深搜,这样一个点进入DFS函数和出DFS函数的时候就会有两个时间点,就是入栈的时间和出栈的时间。然后利用Splay维护一个序列,就是入栈出栈的顺序
BZOJ 1180 CROATIAN 2009 OTOCI/2843 极地旅行社 LCT
]); if(fx == fy) puts("no"); else { puts("yes"); Link(tree[x],tree[y]); } } else if(s[0] == 'p') { Splay(tree[x]); tree[x]->val = y
链剖分】链剖相关总结与心得
剖是fa函数只开一维,只记录其直接父节点(好像是这个样子我没仔细研究过毕竟不写那种) 另一种链剖是蒋一瑶神犇开创的,该种链剖父亲节点使用倍增方式记录,fa[MAXN][18]即这个样子.由于hzwer神犇也是写的这种链剖,我当时也是跟他学的这种链剖. 链剖与LCT的比较 网上普遍认为的是LCT绝大部分时候可以完全代替链剖. 二者的复杂度分别是 O(Q log n) (LCT)和 O(Q log2n) (链剖).后面的差别在于前者是借助Splay维护后者是借助线段维护而且LCT可以实现添边删边等
【codeforces】2014-2015ACM-ICPC CERC 14 Problem J: Pork barrel 【LCT+主席
传送门:【codeforces】2014-2015ACM-ICPC CERC 14 Problem J: Pork barrel 题目分析:pushup内写错了一直没发现。。。把maxidx写成idx然后查了一下午没查出来,到晚饭后才发现。。然后再纠正了数组大小,终于AC了。。。写了我一下午,就因为这么一个小错误T  T 今天是平安夜,祝大家平安夜快乐! 这题是要维护一个最小生成的构造过程。 首先,我们假设这题可以离线! 我们先将边从大到小排序,然后依次连接两点,如果某一次枚举的边的两点
BZOJ 1180 CROATIAN2009 OTOCI Link-Cut-Tree
); Splay(y); x->fa=null; y->ls=null; y->Push_Up(); } int n,m; int main() { //freopen("1180.in","r",stdin); //freopen("1180.out","w",stdout); int i,x,y; char p[100]; cin>>n; for(i=1;i<=n;i++) scanf("%d",&x),tree[i]=new abcd(x); cin>>m
BZOJ 2555 Substring 后缀自动机+Link-Cut-Tree
::Splay(np->tree); np->tree->Add(1); } void Insert() { int i; for(i=1;s[i];i++) Extend(s[i]-'A'); } int Query(char *s) { SAM *p; for(p=root;p;p=p->son[(*s++
hdu4441 Queue Sequence(线段+splay)
不错的题目。解法是线段+splay。 这题充分发挥了线段splay二者的优点,并将各自的操作取长补短,有机的结合了起来。 先来看看这题要我们做什么吧; 首先insert操作中要在p位置插入当前未出现的最小正整数的操作,这个线段比较擅长,统计出现过的正整数,然后直接查找就ok,将其插入p位置,因为有大量的删除操作,也就是说整个操作序列是不断变化的,不仅仅是内容,长度也在不断改变,所以每个位置的数的序号也在时刻改变着,所以线段就不适合完成这样的功能,而这正是splay所擅长的。所以这部分
BZOJ 3514 Codechef MARCH14 GERALD07加强版 LCT+主席
) { ToRoot(tree[e.x]); Access(tree[e.y]); Splay(tree[e.y]); int _min = tree[e.y]->_min; ntr[p] = _min; Cut(tree[edge[_min].x],tree[points + _min]); Cut(tree[edge[_min].y],tree[points + _min
BZOJ 3514 Codechef MARCH14 GERALD07加强版 Link-Cut-Tree+划分
Query(abcd *x,abcd *y) { Move_To_Root(x); Access(y); Splay(y); return y->minnum; } int n,m,q,type,ans; int ntr[M],b[M],c[M],s[20][M]; void Insert(int p) { if(e[p].x==e[p].y) { ntr[p]=p; return ; } abcd *x=tree[e[p].x],*y=tree[e[p].y
BZOJ 2002 弹飞绵羊 Link-Cut-Tree(LCT)
首先这个序列从右往左捋一下肯定是一棵树。错了不对,是一颗森林。 而第二个操作可以随时改变这棵森林的结构 于是这道题很明显是动态树结构中的Link-Cut-Tree。 关于LCT的概念网上有很多 这里只列出一个关键点 就是如何找到链顶的父节点 其实虽然这个算法的实现方式是对每一条重链(想不出名字来了,就沿用轻重链剖分的名字吧)维护一棵Splay,但实质上每一棵树内所有的Splay都是连在一起的。 听不懂?没事,我说过的话我自己也听不懂 拿图来说话 其中加粗的边是重链 这里x所在重链和y所在重链