您的位置:首页 > 其它

Link Cut Tree(动态树)

2017-11-21 11:14 501 查看
模板题

感觉其实LCT就是在用splay维护树剖。。。

贴两个blog

Candy:

https://www.cnblogs.com/candy99/p/6271344.html

zyf2000:

http://blog.csdn.net/clove_unique/article/details/50991804

这两个看完应该就懂了,代码的话,可以抄Candy的

(除了那个诡异的namespace,其他都不错)

我把Candy的代码简单改了改,没啥大变化

看自己的个人习惯,看着哪个顺眼就抄哪个吧

我的代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
inline int read(){
int x=0;char ch=' ';int f=1;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
namespace LCT{
#define lc ch[x][0]
#define rc ch[x][1]
const int N=3e5+5;
int ch
[2],f
,rev
,sum
,val
;
inline bool get(int x){return ch[f[x]][1]==x;}
inline bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
inline void update(int x){sum[x]=sum[lc]^sum[rc]^val[x];}
inline void rever(int x){rev[x]^=1;swap(lc,rc);}
inline void pushdown(int x){
if(rev[x]){
if(lc)rever(lc);
if(rc)rever(rc);
rev[x]=0;
}
}
inline void pd(int x){if(!isroot(x))pd(f[x]);pushdown(x);}
inline void rotate(int x){
int y=f[x],z=f[y],w=get(x);
f[x]=z;if(!isroot(y))ch[z][get(y)]=x;
ch[y][w]=ch[x][w^1];f[ch[y][w]]=y;
ch[x][w^1]=y;f[y]=x;
update(y);update(x);
}
inline void splay(int x){
pd(x);
for(int fa=f[x];!isroot(x);rotate(x),fa=f[x])
if(!isroot(fa))
rotate((get(x)==get(fa))?fa:x);
}
inline void access(int x){
for(int y=0;x;y=x,x=f[x])splay(x),rc=y,update(x);
}
inline void make(int x){
access(x);splay(x);rever(x);
}
inline int find(int x){
access(x);splay(x);
while(lc)x=lc;
return x;
}
inline void split(int x,int y){
make(x);access(y);splay(y);
}
inline void link(int x,int y){
make(x);f[x]=y;
}
inline void cut(int x,int y){
split(x,y);
f[x]=ch[y][0]=0;update(y);
}
}
using namespace LCT;
int n,m;
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)val[i]=read();
while(m--){
int opt=read(),x=read(),y=read();
if(opt==0){split(x,y);printf("%d\n",sum[y]);}
if(opt==1){if(find(x)!=find(y))link(x,y);}
if(opt==2){if(find(x)==find(y))cut(x,y);}
if(opt==3){access(x);splay(x);val[x]=y;update(x);}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: