LG3690 【模板】Link Cut Tree (动态树)
UPD:更新了写法。
【模板】Link Cut Tree
给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。
后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
后接两个整数(x,y),代表连接x到y,若x到y已经联通则无需连接。
后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
后接两个整数(x,y),代表将点x上的权值变成y。
数据范围: \(1 \leq N, M \leq 3 \cdot {10}^5\)
http://www.cnblogs.com/flashhu/p/8324551.html
https://www.cnblogs.com/candy99/p/6271344.html
时间复杂度\(O(n+m \log n)\)
CO int N=100000+10;
int fa[N],ch[N][2],rev[N];
int val[N],sum[N];
#define lc ch[x][0]
#define rc ch[x][1]
IN bool nroot(int x){
return x==ch[fa[x]][0] or x==ch[fa[x]][1];
}
IN void push_up(int x){
sum[x]=sum[lc]^val[x]^sum[rc];
}
IN void push_down(int x){
if(rev[x]){
swap(lc,rc);
rev[lc]^=1,rev[rc]^=1;
rev[x]=0;
}
}
IN void rotate(int x){
int y=fa[x],z=fa[y],l=x==ch[y][1],r=l^1;
if(nroot(y)) ch[z][y==ch[z][1]]=x;fa[x]=z;
ch[y][l]=ch[x][r],fa[ch[x][r]]=y;
ch[x][r]=y,fa[y]=x;
push_up(y);
}
void splay(int x){
vector<int> stk(1,x);
for(int i=x;nroot(i);) stk.push_back(i=fa[i]);
for(;stk.size();stk.pop_back()) push_down(stk.back());
for(;nroot(x);rotate(x)){
int y=fa[x],z=fa[y];
if(nroot(y)) rotate((x==ch[y][1])!=(y==ch[z][1])?x:y);
}
push_up(x);
}
void access(int x){
for(int y=0;x;y=x,x=fa[x])
splay(x),rc=y,push_up(x);
}
void make_root(int x){
access(x),splay(x),rev[x]^=1;
}
int find_root(int x){
access(x),splay(x);
while(lc) x=lc;
splay(x);
return x;
}
#undef lc
#undef rc
int main(){
int n=read<int>(),m=read<int>();
for(int i=1;i<=n;++i) read(val[i]);
while(m--)switch(read<int>()){
case 0:{
int x=read<int>(),y=read<int>();
make_root(x),access(y),splay(y);
printf("%d\n",sum[y]);
break;
}
case 1:{
int x=read<int>(),y=read<int>();
make_root(x);
if(find_root(y)!=x) fa[x]=y;
break;
}
case 2:{
int x=read<int>(),y=read<int>();
make_root(x);
if(find_root(y)==x and fa[y]==x and !ch[y][0]){
fa[y]=ch[x][1]=0;
push_up(x);
}
break;
}
default:{
int x=read<int>();
splay(x),read(val[x]),push_up(x);
break;
}
}
return 0;
}
洞穴勘测
辉辉热衷于洞穴勘测。某天,他按照地图来到了一片被标记为JSZX的洞穴群地区。经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴。假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径。洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通道,有时这条通道又会因为某种稀奇古怪的原因被毁。
辉辉有一台监测仪器可以实时将通道的每一次改变状况在辉辉手边的终端机上显示:
如果监测到洞穴u和洞穴v之间出现了一条通道,终端机上会显示一条指令 Connect u v
如果监测到洞穴u和洞穴v之间的通道被毁,终端机上会显示一条指令 Destroy u v
经过长期的艰苦卓绝的手工推算,辉辉发现一个奇怪的现象:无论通道怎么改变,任意时刻任意两个洞穴之间至多只有一条路径。因而,辉辉坚信这是由于某种本质规律的支配导致的。因而,辉辉更加夜以继日地坚守在终端机之前,试图通过通道的改变情况来研究这条本质规律。然而,终于有一天,辉辉在堆积成山的演算纸中崩溃了……他把终端机往地面一砸(终端机也足够坚固无法破坏),转而求助于你,说道:“你老兄把这程序写写吧”。
辉辉希望能随时通过终端机发出指令 Query u v,向监测仪询问此时洞穴u和洞穴v是否连通。现在你要为他编写程序回答每一次询问。已知在第一条指令显示之前,JSZX洞穴群中没有任何通道存在。
100%的数据满足n≤10000, m≤200000
保证所有Destroy指令将摧毁的是一条存在的通道
LCT模板题,总结了一下我所见过的最简洁的写法。时间复杂度\(O(m \log n)\)
co int N=1e4+1;
namespace T{
int fa[N],ch[N][2],st[N],rev[N];
#define lc ch[x][0]
#define rc ch[x][1]
bool nroot(int x){return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
void pushdown(int x){
if(rev[x]){
std::swap(lc,rc);
rev[lc]^=1,rev[rc]^=1;
rev[x]=0;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],l=x==ch[y][1],r=l^1;
if(nroot(y)) ch[z][y==ch[z][1]]=x;fa[x]=z;
ch[y][l]=ch[x][r],fa[ch[x][r]]=y;
ch[x][r]=y,fa[y]=x;
}
void splay(int x){
int y=x,z=0;
st[++z]=y;
while(nroot(y)) st[++z]=y=fa[y];
while(z) pushdown(st[z--]);
for(;nroot(x);rotate(x)){
y=fa[x],z=fa[y];
if(nroot(y)) rotate(y==ch[z][1]^x==ch[y][1]?x:y);
}
}
void access(int x){
for(int y=0;x;x=fa[y=x])
splay(x),rc=y;
}
void makeroot(int x){
access(x),splay(x),rev[x]^=1;
}
int findroot(int x){
access(x),splay(x);
while(lc) x=lc;
return x;
}
void link(int x,int y){
makeroot(x),fa[x]=y;
}
void cut(int x,int y){
makeroot(x),access(y),splay(y),ch[y][0]=fa[x]=0;
}
}
int main(){
int n=read<int>(),m=read<int>();
char opt[10];
int x,y;
while(m--){
scanf("%s",opt);
read(x),read(y);
if(opt[0]=='C') T::link(x,y);
else if(opt[0]=='D') T::cut(x,y);
else puts(T::findroot(x)==T::findroot(y)?"Yes":"No");
}
return 0;
}
LG3690 【模板】Link Cut Tree (动态树)的更多相关文章
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷.3690.[模板]Link Cut Tree(动态树)
题目链接 LCT(良心总结) #include <cstdio> #include <cctype> #include <algorithm> #define gc ...
- Link Cut Tree 动态树 小结
动态树有些类似 树链剖分+并查集 的思想,是用splay维护的 lct的根是动态的,"轻重链"也是动态的,所以并没有真正的轻重链 动态树的操作核心是把你要把 修改/询问/... 等 ...
- LCT(link cut tree) 动态树
模板参考:https://blog.csdn.net/saramanda/article/details/55253627 综合各位大大博客后整理的模板: #include<iostream&g ...
- 洛谷P3690 Link Cut Tree (动态树)
干脆整个LCT模板吧. 缺个链上修改和子树操作,链上修改的话join(u,v)然后把v splay到树根再打个标记就好. 至于子树操作...以后有空的话再学(咕咕咕警告) #include<bi ...
- 洛谷P3690 [模板] Link Cut Tree [LCT]
题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...
- 模板Link Cut Tree (动态树)
题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联 ...
- 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
随机推荐
- vs 2017 保存文件 utf8
vs 2017 保存文件 utf8 转自:https://blog.csdn.net/jiegemena/article/details/79369650
- javascript的几种使用多行字符串的方式
JS里并没有标准的多行字符串的表示方法,但是在用模板的时候,为了保证模板的可阅读性,我们又不可避免的使用多行字符串,所以出现了各种搞法,这里以一段jade的模板作为示例,简单总结和对比一下. 字符串相 ...
- Ngix
Ngix安装 官网地址,下载为源码,需要编译安装 http://nginx.org/ 环境 1.需要安装gcc的环境. yum install gcc-c++ 2.第三方的开发包. PCRE PCRE ...
- tarball安装GnuPG (gpg) 2.2.10
https://www.gnupg.org/download/ mac 方式一:推荐 mac $ brew install gpg pinentry pinentry-mac $ echo " ...
- yii2手动添加插件PHPExcel
1.下载地址:https://github.com/PHPOffice/PHPExcel 2.解压并修改文件名为phpexcel 之后在yii项目的vendor目录下创建一个文件夹命名为phpoffi ...
- 浅谈HTML中的块级元素和内联元素
一.基本概念 1.块级元素(block element):一般都从新行开始占据一定的矩形空间,可以设置其宽.高属性来改变矩形的大小.一般情况下块级元素可以包含内联元素和其它块级元素,但也有特殊如for ...
- CSS样式--移动划过超链接鼠标变手型详解
用css控制鼠标样式的语法如下:<span style="cursor:*">文本或其它页面元素</span>把 * 换成如下15个效果的一种: 下面是对这 ...
- Spring入门5.事务管理机制
Spring入门5.事务管理机制 20131126 代码下载 : 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 回顾之前的知识,Spring 最为核心的两个部分 ...
- Java复习3.变量.常量.String.
Java 中的变量常量数据类型 20131004 前言: 还是国庆节,无聊的很,就没事复习点Java的知识,其实C/C++基本上是现在大型企业面试的语言,但是多学习点Java是没有坏处的,而且,将来工 ...
- Node.js 全栈开发(一)——Web 开发技术演化
这些年一直不断接触学习 Node 技术栈,个人的技术开发学习兴趣也越来越倾向 node 流.也许是由于英语的关系,也许是因为墙增加了学习国外一手资料的难度,加上现在流行的 web 开发技术并不太容易上 ...