Link-Cut-Tree 题目总结
Posted bxd123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Link-Cut-Tree 题目总结相关的知识,希望对你有一定的参考价值。
P3690 【模板】Link Cut Tree (动态树)
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<‘=‘<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// const int N=2e6+10; int fa[N],val[N],sum[N],son[N][2],rev[N],st[N]; int get(int x)return son[fa[x]][0]==x||son[fa[x]][1]==x; void up(int x)sum[x]=sum[son[x][1]]^sum[son[x][0]]^val[x]; void change(int x)swap(son[x][0],son[x][1]);rev[x]^=1; void down(int x) if(!rev[x])return ; rev[x]=0; if(son[x][0])change(son[x][0]); if(son[x][1])change(son[x][1]); void rotate(int x) int y=fa[x],z=fa[y],k=son[fa[x]][1]==x,w=son[x][k^1]; if(get(y))son[z][son[z][1]==y]=x;son[x][k^1]=y;son[y][k]=w; if(w)fa[w]=y;fa[y]=x;fa[x]=z; up(y);up(x); void splay(int x) int y=x,top=0;st[++top]=y; while(get(y))st[++top]=y=fa[y]; while(top)down(st[top--]); while(get(x)) int y=fa[x],z=fa[y]; if(get(y)) rotate((son[y][0]==x)^(son[z][0]==y)?x:y); rotate(x); up(x); void access(int x) for(int y=0;x;x=fa[y=x]) splay(x),son[x][1]=y,up(x); void makeroot(int x) access(x);splay(x);change(x); int findroot(int x) access(x);splay(x); while(son[x][0])down(x),x=son[x][0]; splay(x);return x; void split(int x,int y) makeroot(x);access(y);splay(y); void link(int x,int y) makeroot(x);if(findroot(y)!=x)fa[x]=y; void cut(int x,int y) split(x,y); if(findroot(y)==x&&fa[y]==x&&!son[y][0]) fa[y]=son[x][1]=0,up(x); int n,m,x,y,op; int main() scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&val[i]); while(m--) scanf("%d%d%d",&op,&x,&y); if(op==0)split(x,y),printf("%d\\n",sum[y]); if(op==1)link(x,y); if(op==2)cut(x,y); if(op==3)splay(x),val[x]=y;//这里不up也没事 反正问的时候也会up return 0;
P2147 [SDOI2008]洞穴勘测
题意: 就是可删除的并查集
题解: 没啥好说的 比模板简单
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<‘=‘<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) //////////////////////////////////// const int N=2e6+10; int fa[N],son[N][2],rev[N],st[N]; int get(int x)return son[fa[x]][0]==x||son[fa[x]][1]==x; void change(int x)swap(son[x][1],son[x][0]);rev[x]^=1; void down(int x) if(!rev[x])return ; rev[x]=0; if(son[x][1])change(son[x][1]); if(son[x][0])change(son[x][0]); void rotate(int x) int y=fa[x],z=fa[y],k=son[fa[x]][1]==x,w=son[x][k^1]; if(get(y))son[z][son[z][1]==y]=x;son[x][k^1]=y;son[y][k]=w; if(w)fa[w]=y;fa[y]=x;fa[x]=z; void splay(int x) int y=x,top=0;st[++top]=y; while(get(y))st[++top]=y=fa[y]; while(top)down(st[top--]); while(get(x)) int y=fa[x],z=fa[y]; if(get(y)) rotate((son[y][0]==x)^(son[z][0]==y)?x:y); rotate(x); void access(int x) for(int y=0;x;x=fa[y=x]) splay(x),son[x][1]=y; void makeroot(int x) access(x);splay(x);change(x); int findroot(int x) access(x);splay(x); while(son[x][0])down(x),x=son[x][0]; splay(x);return x; void split(int x,int y) makeroot(x);access(y);splay(y); void link(int x,int y) makeroot(x); if(findroot(y)!=x)fa[x]=y; bool judge(int x,int y) makeroot(x); return findroot(y)==x; void cut(int x,int y) split(x,y); if(findroot(y)==x&&fa[y]==x&&!son[y][0]) fa[y]=son[x][1]=0; char s[100];int n,m,x,y; int main() scanf("%d%d",&n,&m); while(m--) scanf("%s %d%d",s,&x,&y); if(s[0]==‘Q‘)printf("%s\\n",judge(x,y)?"Yes":"No"); if(s[0]==‘C‘)link(x,y); if(s[0]==‘D‘)cut(x,y); return 0;
以上是关于Link-Cut-Tree 题目总结的主要内容,如果未能解决你的问题,请参考以下文章
对于动态树 (Link-Cut-Tree, LCT) 的理解与总结