bzoj3673: 可持久化并查集 by zky&&3674: 可持久化并查集加强版

主席树可持久化数组,还挺好YY的

然而加强版要路径压缩。。

发现压了都RE

结果看了看数据,默默的把让fx的父亲变成fy反过来让fy的父亲变成fx

搞笑啊

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int n;
struct chairman_tree
{
    int lc,rc,c;
}tr[1300000];int trlen,rt[410000];
int maketree(int now,int l,int r,int p,int k)
{
    if(now==0)now=++trlen;
    tr[now].lc=tr[now].rc=0;
    tr[now].c=-1;
    
    if(l==r)tr[now].c=k;
    else
    {
        int mid=(l+r)/2;
        if(p<=mid)tr[now].lc=maketree(tr[now].lc,l,mid,p,k);
        else       tr[now].rc=maketree(tr[now].rc,mid+1,r,p,k);
    }
    return now;
}
int merge(int x,int y)
{
    if(x==0||y==0)return x+y;
    tr[x].lc=merge(tr[x].lc,tr[y].lc);
    tr[x].rc=merge(tr[x].rc,tr[y].rc);
    return x;
}

int gofind(int now,int l,int r,int p)
{
    if(l==r)return tr[now].c;
    int mid=(l+r)/2;
    if(p<=mid)return gofind(tr[now].lc,l,mid,p);
    else       return gofind(tr[now].rc,mid+1,r,p);
}
int findfa(int t,int x)
{
    int F=gofind(rt[t],1,n,x);
    if(F==x)return x;
    int tf=findfa(t,F);
    if(tf!=F)
    {
        int root=rt[t];
        rt[t]=maketree(0,1,n,x,tf);
        rt[t]=merge(rt[t],root);
    }
    return tf;
}

int main()
{
    freopen("disjoint.in","r",stdin);
    freopen("disjoint.out","w",stdout);
    int Q;
    scanf("%d%d",&n,&Q);
    trlen=0;memset(rt,0,sizeof(rt));
    for(int i=1;i<=n;i++)
    {
        rt[i]=maketree(rt[i],1,n,i,i);
        rt[i]=merge(rt[i],rt[i-1]);
    }
    
    int op,x,y,tim=0,ans=0;
    while(Q--)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&x,&y);
            int fx=findfa(tim+n,x);
            int fy=findfa(tim+n,y);
            tim++;
            rt[tim+n]=maketree(rt[tim+n],1,n,fy,fx);
            rt[tim+n]=merge(rt[tim+n],rt[tim+n-1]);
        }
        else if(op==2)
        {
            scanf("%d",&x);
            tim++;
            rt[tim+n]=rt[x+n];
        }
        else
        {
            scanf("%d%d",&x,&y);
            int fx=findfa(tim+n,x);
            int fy=findfa(tim+n,y);
            ans=(fx==fy);
            printf("%d\n",ans);
            tim++;
            rt[tim+n]=rt[tim+n-1];
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AKCqhzdy/p/9445569.html