Link Cut Tree

其实本人觉得LCT对于已经学过树剖与Splay的大佬是很容易理解接受的;

LCT是有树链与Splay结合而成的动态树;什么是动态树呢,就是维护森林的联通性的总称;

先介绍一些概念:

1.prefered child:最后被它的点在x的儿子p节点的子树中,那么p为x的偏爱子节点(相当于树剖中的重儿子)

2.prefered edge:父节点与它的偏爱子节点的边(相当于树剖中的重边)

3.prefered path:由偏爱边连接而成的路径为偏爱路径(相当于树剖中的重链)

我们学LCT时可以发现,每个点只在一条prefered path上,那么这样的话所有的prefered path就可以表示整棵树了,我们可以在每条prefered path 上建一棵splay,关键字为深度

也就是在每棵Splay中,左节点的深度都比当前节点小,右节点的深度都比当前节点深度大;这样,每棵spaly我们把它称作Auxiliary tree(辅助树),每棵辅助树的根节点的父亲

保存与上一棵辅助树的哪个点相连;整棵Splay在原树上相当于一条链(中序遍历);

原树中的深度是递增的,辅助树中的左右子树是以深度为权值的!

易混点:

   原树的根节点!=辅助树中的根节点

   原树的左右儿子不等于辅助树的左右儿子

现在来说下一些基本操作:

1.access(x) 访问x节点:切断x与其原先Prefered child 的联系,由于prefered path与prefered child的定义,我们访问一个节点,那么这个点到根节点的所有边都是prefered edge;由于每个点只能有一个prefered child;所以我们需把节点与它原来的prefered child断开,连接这条新的prefered path;先把x splay到根节点,然后更新它的右子节点,直到x的fa 为空;

2.make root(x) access(x)后,splay到根,然后由于权值是深度,所以为了维护左子树权值小于右子树性质,我们还需区间翻转一下;

3.link(x,y) 连边,只需makeroot(x),然后把x的父亲指向y即可;

4.cut(x,y) 删边,先makeroot(x),然后access(y),此时x与y已在同一棵splay中,然后再splay(y),那么x就在y的左儿子中;

最后放下代码:(luogu 3690)

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #define maxn 300233
  5 using namespace std;
  6 int stack[maxn];
  7 struct hh{
  8     int c[2],fa,val,sum;
  9     bool rev;
 10 }tree[maxn];
 11 int read(){
 12     int s=0;
 13     char c=getchar();
 14     while(c<48||c>57) c=getchar();
 15     while(c>=48&&c<=57){
 16     s=s*10+c-48;c=getchar();}
 17     return s;
 18 }
 19
 20 inline void update(int x){
 21     tree[x].sum=tree[tree[x].c[0]].sum^tree[x].val
 22     ^tree[tree[x].c[1]].sum;
 23 }
 24 inline void pushdown(int x){
 25     if(!tree[x].rev) return;
 26     int l=tree[x].c[0],r=tree[x].c[1];
 27     if(l) tree[l].rev^=1;
 28     if(r) tree[r].rev^=1;
 29     swap(tree[x].c[0],tree[x].c[1]);
 30     tree[x].rev^=1;
 31 }
 32 bool isroot(int x){
 33     return tree[tree[x].fa].c[0]!=x&&tree[tree[x].fa].c[1]!=x;
 34 }
 35 bool get(int x) {
 36 return x==tree[tree[x].fa].c[1];}
 37 void rotate(int x){
 38     int f=tree[x].fa,ff=tree[tree[x].fa].fa,opt=get(x);
 39     tree[f].c[opt]=tree[x].c[opt^1];
 40     tree[tree[x].c[opt^1]].fa=f;
 41     if(!isroot(f)) tree[ff].c[get(f)]=x;
 42     tree[x].fa=ff;tree[f].fa=x;
 43     tree[x].c[opt^1]=f;
 44     update(f);update(x);
 45 }
 46 void splay(int x){
 47     //pushdown(x);
 48     int top=0,tmp=x;stack[++top]=x;
 49     while(!isroot(tmp))stack[++top]=tree[tmp].fa,tmp=tree[tmp].fa;
 50     while(top)pushdown(stack[top]),top--;
 51     while(!isroot(x)){
 52     //    if(!isroot(tree[x].fa)) rotate(get(tree[x].fa)==get(x)?tree[x].fa:x);
 53     //    x=tree[x].fa;
 54         rotate(x);
 55     }
 56 }
 57 void access(int x){
 58     int son=0;
 59     while(x){
 60         splay(x);tree[x].c[1]=son;
 61         update(x);son=x;x=tree[x].fa;
 62     }
 63 }
 64 void makeroot(int x){
 65     access(x);splay(x);tree[x].rev^=1;
 66 }
 67 void link(int x,int y){
 68     makeroot(x);tree[x].fa=y;
 69     splay(x);
 70 }
 71 void cut(int x,int y){
 72     makeroot(x);access(y);
 73     splay(y);tree[y].c[0]=tree[x].fa=0;
 74 }
 75 int query(int x,int y){
 76     makeroot(x);access(y);splay(y);
 77     return tree[y].sum;
 78 }
 79 int getfa(int x){
 80     access(x);splay(x);
 81     while(tree[x].c[0]){
 82         pushdown(x);x=tree[x].c[0];
 83         splay(x);
 84     }
 85     return x;
 86 }
 87 void change(int x,int y){
 88     makeroot(x);
 89     tree[x].val=y;
 90     update(x);
 91 }
 92 int main(){
 93     int n,m,i,x,y,opt;
 94     n=read();m=read();
 95     for(i=1;i<=n;i++){
 96         tree[i].val=read();
 97         tree[i].sum=tree[i].val;
 98     }
 99     while(m--){
100         opt=read();x=read();y=read();
101         if(opt==0) printf("%d\n",query(x,y));
102         else if(opt==1) {if(getfa(x)!=getfa(y))link(x,y);}
103         else if(opt==2) {if(getfa(x)==getfa(y)) cut(x,y);}
104         else change(x,y);}
105 }

View Code

转载于:https://www.cnblogs.com/Fish-/p/8167122.html

[Data]Link cut tree相关推荐

  1. 15行代码AC——Link/Cut Tree CodeForces - 614A(爆long long处理+快速幂讲解)

    励志用少的代码做高效表达 Problem describe Programmer Rostislav got seriously interested in the Link/Cut Tree dat ...

  2. Link Cut Tree详解

    Link Cut Tree ==Warning:千万不要跳读== 参考博客:https://www.cnblogs.com/flashhu/p/8324551.html 什么是动态树? 动态树问题, ...

  3. 模板:Link Cut Tree(LCT)

    文章目录 前言 解析 原理 rotate(x) splay(x) access(x) findroot(x) makeroot(x) split(x,y) link(x,y) cut(x,y) pus ...

  4. Link Cut Tree 学习笔记

    Link Cut Tree 学习笔记 说在前边 最近补 CF 碰见一道 LCT ,就打算学习一下这个东西...顺便复习一下 splay. 具体算法及实现 参考了FlashHu, Candy? P369 ...

  5. Link/Cut Tree学习笔记

    最近正是实验课的高峰期,我数了一下,除了毛概没有实验课,其他的课都有实验课...不过好在这些实验都不是很难.我尽力挤出时间用来刷题. 简介 Link/Cut Tree和树链剖分很相似,二者处理的问题也 ...

  6. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  7. 洛谷 - P3690 【模板】Link Cut Tree (动态树)(LCT模板)

    题目链接:点击查看 题目大意:给出 n 个带权节点,需要执行 m 次操作,每次操作分为四种类型: 0 x y 代表询问从 x 到 y 的路径上的点的权值的 xor 和.保证 x 到 y 是联通的. 1 ...

  8. luogu P3690 【模板】Link Cut Tree (动态树)

    嘟嘟嘟 LCT竟然看了整整一天,但好歹是看懂了. 教程这里不写,强烈推荐 闪狐大佬的博客 . 但是还是有几句想说的. 1.尽管LCT和splay很像,但是有一些细节还是不一样的.首先是rotate,我 ...

  9. Link Cut Tree学习笔记

    捋一下思路 模板题:https://www.luogu.org/problemnew/show/P3690 推荐LCT的教程,个人认为很详细,本文做了部分引用:https://www.luogu.or ...

  10. P3690-[模板]Link Cut Tree(动态树)【Splay】

    正题 题目链接:https://www.luogu.org/problem/P3690 题目大意 nnn个点mmm个操作,要求支持 询问路径异或和 连接一条边(若x,yx,yx,y没联通) 删除一条边 ...

最新文章

  1. 数学表达式解析器简介
  2. python爬虫用urllib还是reques,python爬虫中urllib.request和requests有什么区别?
  3. 浏览器插件 火狐插件
  4. 操作系统中避免死锁的银行家算法【表面C++实际C语言】一学就废的菜鸡代码
  5. sql server 游标的使用方法
  6. 新一代企业操作系统:专属钉钉解决方案全新上线
  7. C++ const对象
  8. 一起来学SpringBoot | 第四篇:整合Thymeleaf模板
  9. 轻量级HTTP服务器Nginx(Nginx性能优化技巧)
  10. mysql中更新的命令是_MySQL 语言中,更新表数据的命令是( )。_学小易找答案
  11. 代码块(block)之函数体(二)
  12. MySQL 到底能不能放到 Docker 里跑? 1
  13. 2021-2025年中国IT业的利好机遇
  14. ecmobile php开发文档,ecmobile PHP接口说明文档之购物车(cart/create|list|detele|update)
  15. mysql每五分钟取一次数据_mysql – 给定时间内每5分钟的平均数据
  16. 2021-12-12
  17. 26个颠覆世界的 3D 打印产品,未来将会创造另一个新的世界
  18. 携手共进 智享未来丨美格智能2023年代理商合作伙伴大会成功举办
  19. Ollydbg使用技巧
  20. android webrtc教程,WebRTC 入门教程(一)| 搭建WebRTC信令服务器

热门文章

  1. gtx1050ti最稳定的驱动_最便宜图灵吃鸡卡 华硕GTX 1650评测
  2. javascript基础之拖拽(1)(详细篇)--dataTransfer对象
  3. linux ubuntu/centos相关收藏
  4. 洛谷P3233 [HNOI2014]世界树
  5. href 和 src 区别
  6. VM虚拟机,Linux系统安装tools过程遇到 what is the location of the “ifconfig” program
  7. 做一个消息自动回复,但是回复内容可以在网页上面输入,用input接收,错了,别人有新增选项,本身就是在页面进行新增,页面维护...
  8. 那些盒模型在IE6中的BUG们,工程狮的你可曾遇到过?
  9. (转)MapReduce二次排序
  10. 微软高性能网络编程示例程序