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;
View Code

 

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;
View Code

 

以上是关于Link-Cut-Tree 题目总结的主要内容,如果未能解决你的问题,请参考以下文章

对于动态树 (Link-Cut-Tree, LCT) 的理解与总结

Link-Cut-Tree 动态树算法

SPOJQTREE6(Link-Cut-Tree)

bzoj1036: [ZJOI2008]树的统计Count link-cut-tree版

bzoj2631tree link-cut-tree

bzoj4764: 弹飞大爷 link-cut-tree