洛谷P3690 LCT模板

题目:https://www.luogu.org/problemnew/show/P3690

自己竟然从没有钻研过LCT上的连通性问题!

于是被最后一个点卡了,似乎因为 find 函数只能找出连通性而不能判断有没有直接相连的边;

所以还是直接在 cut 函数里判断一下好了。

(注:第9个点时T时不T的,不想去管它了。)

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=3e5+5;
int n,m,fa[maxn],c[maxn][3],sum[maxn],w[maxn],rev[maxn],sta[maxn],top;
bool isroot(int x){return c[fa[x]][0]!=x && c[fa[x]][1]!=x;}
void pushup(int x)
{
    sum[x]=(sum[c[x][0]]^sum[c[x][1]]^w[x]);
}
void reverse(int x)
{
    if(rev[x])
    {
        rev[c[x][0]]^=1; rev[c[x][1]]^=1; rev[x]=0;
        swap(c[x][0],c[x][1]);
    }
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],d=(c[y][1]==x);
    if(!isroot(y))c[z][c[z][1]==y]=x;
    fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
    c[y][d]=c[x][!d]; c[x][!d]=y;
    pushup(y); pushup(x);
}
void splay(int x)
{
    sta[top=1]=x;
    for(int i=x;!isroot(i);i=fa[i])sta[++top]=fa[i];
    for(;top;top--)reverse(sta[top]);
    for(;!isroot(x);rotate(x))
    {
        int y=fa[x],z=fa[y];
        if(isroot(y))continue;
        ((c[y][0]==x)^(c[z][0]==y))?rotate(x):rotate(y);
    }
}
void access(int x)
{
    for(int t=0;x;c[x][1]=t,pushup(x),t=x,x=fa[x])splay(x);
}
void makeroot(int x)
{
    access(x); splay(x); rev[x]^=1;
}
void link(int x,int y)
{
    makeroot(x); fa[x]=y;
}
void query(int x,int y)
{
    makeroot(x); access(y); splay(y);
}
void cut(int x,int y)
{
    query(x,y);
    if(c[y][0]!=x)return;//!
    fa[x]=0; c[y][0]=0;
}
int find(int x)
{
    access(x); splay(x); while(c[x][0])x=c[x][0]; return x;
}
void change(int u,int t)
{
    makeroot(u); w[u]=t; pushup(u);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    for(int i=1,op,x,y;i<=m;i++)
    {
        scanf("%d%d%d",&op,&x,&y);
        if(op==0){query(x,y); printf("%d\n",sum[y]);}
        if(op==1)
        {
            if(find(x)==find(y))continue;
            link(x,y);
        }
        if(op==2)
        {
//            if(find(x)!=find(y))continue;
            cut(x,y);
        }
        if(op==3)change(x,y);
    }
    return 0;
}
/*
5 6
1
2
3
4
5
1 1 2
1 2 3
1 3 4
1 4 5
2 1 5
0 1 5


1
*/

猜你喜欢

转载自www.cnblogs.com/Zinn/p/9248465.html
今日推荐