Link-Cut-Tree学习(LCT)

真不敢想象我居然学会LCT了,但是我仍然不想写一篇博客来梳理

我怕一梳理自己又不懂了

但是作为一名朴实沉毅的cjoier,我决定小小的梳理一下,并不打算很精致......

我这样说也是有资本的,下面推荐两个教会我LCT的博客

FlashHu的总结+题单+升级

xzy的题单+好板子

其实贴上这两个博客也就没我什么事了,所以,溜了溜了

以后我想复习了直接就点开QwQ

code

当然,一贯不要脸的我,明明自己的代码是看的xzy的,还是附上了自己的代码

PS:不得不承认,set是个好东西啊

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#define rg register
#define il inline
#define lst long long
#define ldb long double
#define N 300050
using namespace std;
const int Inf=1e9;
il int read()
{
rg int s=0,m=0;rg char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
} int n,m,top;
int st[N];
set<int> link[N];
struct SPLAY{int fa,v,sum,tag,ch[2];}ljl[N]; il void Pushup(rg int x){ljl[x].sum=ljl[ljl[x].ch[0]].sum^ljl[ljl[x].ch[1]].sum^ljl[x].v;}
il void Reverse(rg int x){swap(ljl[x].ch[0],ljl[x].ch[1]);ljl[x].tag^=1;}
il void Pushdown(rg int x)
{
if(ljl[x].tag)
{
if(ljl[x].ch[0])Reverse(ljl[x].ch[0]);
if(ljl[x].ch[1])Reverse(ljl[x].ch[1]);
ljl[x].tag=0;
}
}
il bool Isroot(rg int x){return ((ljl[ljl[x].fa].ch[0]!=x)&&(ljl[ljl[x].fa].ch[1]!=x));}
il void Rotate(rg int x)
{
rg int y=ljl[x].fa,z=ljl[y].fa;
rg int k=ljl[y].ch[1]==x;
if(!Isroot(y))ljl[z].ch[ljl[z].ch[1]==y]=x;
ljl[x].fa=z;
ljl[y].ch[k]=ljl[x].ch[k^1];
ljl[ljl[x].ch[k^1]].fa=y;
ljl[x].ch[k^1]=y;
ljl[y].fa=x;
Pushup(y);
}
il void Splay(rg int x)
{
st[++top]=x;
for(rg int i=x;!Isroot(i);i=ljl[i].fa)st[++top]=ljl[i].fa;
while(top)Pushdown(st[top--]);
while(!Isroot(x))
{
rg int y=ljl[x].fa,z=ljl[y].fa;
if(!Isroot(y))(ljl[y].ch[0]==x)^(ljl[z].ch[0]==y)?Rotate(x):Rotate(y);
Rotate(x);
}
Pushup(x);
} il void Access(rg int x)
{
for(rg int y=0;x;y=x,x=ljl[x].fa)
Splay(x),ljl[x].ch[1]=y,Pushup(x);
}
il void Make_root(rg int x){Access(x),Splay(x),Reverse(x);}
il int Find_root(rg int x)
{
Access(x),Splay(x);
while(ljl[x].ch[0])x=ljl[x].ch[0];
return x;
}
il void Split(rg int x,rg int y){Make_root(x),Access(y),Splay(y);}
il void Link(rg int x,rg int y)
{
Make_root(x),ljl[x].fa=y;
link[x].insert(y),link[y].insert(x);
}
il void Cut(rg int x,rg int y)
{
Split(x,y);
ljl[x].fa=ljl[y].ch[0]=0;
link[x].erase(y),link[y].erase(x);
} int main()
{
freopen("s.in","r",stdin);
n=read(),m=read();
for(rg int i=1;i<=n;++i)
ljl[i].sum=ljl[i].v=read();
for(rg int i=1;i<=m;++i)
{
rg int opt=read(),x=read(),y=read();
if(opt==0)//x--y异或和
{
Split(x,y);//抠出路径,此时这条路径的异或和存在SPLAY根节点y中
printf("%d\n",ljl[y].sum);//直接输出sum[y]就ok
}
if(opt==1)//连接x--y
if(Find_root(x)^Find_root(y))Link(x,y);//如果不是同一个联通块里就连边
if(opt==2)//删除x--y
if(link[x].find(y)!=link[x].end())Cut(x,y);//如果x所连的边中找到了y(没有找到set尾部)就删边
if(opt==3)//把x的权值改为y
{
Access(x),Splay(x);//把x抠出来并放到SPLAY的根节点(不会影响到其他元素的sum)
ljl[x].v=y,Pushup(x);//直接修改就行,顺便更新一下自己
}
}
return 0;
}

Link-Cut-Tree学习(LCT)的更多相关文章

  1. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  2. Luogu P3690【模板】Link Cut Tree (LCT板题)

    省选前刷道LCT板题(话说之前没做这道题-) CODE #include<bits/stdc++.h> using namespace std; inline void read(int ...

  3. LUOGU P3690 【模板】Link Cut Tree (lct)

    传送门 解题思路 \(lct\)就是基于实链剖分,用\(splay\)来维护每一条实链,\(lct\)的维护对象是一棵森林.\(lct\)支持很多神奇的操作: \(1.\) \(access\):这是 ...

  4. 洛谷P3690 【模板】Link Cut Tree (LCT)

    题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...

  5. LuoguP3690 【模板】Link Cut Tree (LCT)

    勉强算是结了个大坑吧或者才开始 #include <cstdio> #include <iostream> #include <cstring> #include ...

  6. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  7. 洛谷P3690 [模板] Link Cut Tree [LCT]

    题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...

  8. LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板

    P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...

  9. 学习笔记:Link Cut Tree

    模板题 原理 类似树链剖分对重儿子/长儿子剖分,Link Cut Tree 也做的是类似的链剖分. 每个节点选出 \(0 / 1\) 个儿子作为实儿子,剩下是虚儿子.对应的边是实边/虚边,虚实时可以进 ...

  10. link cut tree 入门

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

随机推荐

  1. Spark2.0集成Hive操作的相关配置与注意事项

    前言 已完成安装Apache Hive,具体安装步骤请参照,Linux基于Hadoop2.8.0集群安装配置Hive2.1.1及基础操作 补充说明 Hive中metastore(元数据存储)的三种方式 ...

  2. Cocos2d-x视频教程

    目录 1. 我的技术专栏 2. 相关推荐 3. 下载链接 4. cocos2d-xx Lua+JS+C++教学视频 5. 杨丰盛Cocos2D-X游戏课程 6. [Cocos2d-x]塔防游戏开发实战 ...

  3. etc/pass命令列表

    用户 密码 用户UID 用户组GID 备注 home目录位置 默认shell root x 0 0 root /root /bin/bash daemon x 1 1 daemon /usr/sbin ...

  4. 苹果账号需要的邓白氏D-U-N-S编码更新信息最新方法,官方已不受理邮件

    公司从上海搬迁到深圳,公司名称相应变更,但之前注册的苹果开发者账号上的名字还是就的,尝试在后台提交更新申请,官方给了邮件,要求邮件提交证明材料,证明材料提交后,苹果又反馈和邓白氏的资料不匹配,要求先修 ...

  5. 微信支付签名算法JavaScript版,参数名ASCII码从小到大排序;0,A,B,a,b;

    // 支付md5加密获取sign paysignjs: function (jsonobj) { var signstr = this.obj2str(jsonobj) signstr = signs ...

  6. 04.Linux-CentOS系统sudo权限配置

    visudo权限配置普通用户的使用权限范围配置文件: (请根据自己公司需求配置) [root@localhost ~]# visudo ## Allow root to run any command ...

  7. nginx多层反代配置变量proxy_set_header

    Nginx多层反代配置变量proxy_set_header过程记录 第一层代理: (1)路径: $ vim /data/soft/nginx/conf/vhost/xixi.conf (2)内容:(注 ...

  8. 【学习】006数据交换格式与SpringIOC底层实现

    课程目标 XML和JSON Java反射机制 手写SpringIOC 什么是数据交换格式 客户端与服务器常用数据交换格式xml.json.html 数据交换格式用场景 移动端(安卓.IOS)通讯方式采 ...

  9. Linux下安装Python,以及环境变量的配置

    1.安装环境   centos7 + vmware + xshell 2.安装Python3 2.1下载Python资源包 网址:https://www.python.org/downloads/re ...

  10. asp.net开发微信公众平台----目录汇总-持续更新

    1.[c#]asp.net微信公众平台开发(1)数据库设计 2.[c#]asp.net微信公众平台开发(2)多层架构框架搭建和入口实现 3.[c#]asp.net微信公众平台开发(3)微信消息封装及反 ...