bzoj3673&3674 可持久化并查集

来源:互联网 发布:海岛奇兵妹子升级数据 编辑:程序博客网 时间:2024/05/18 00:36

题意如题。。。

分析:可持久化并查集可以用主席树维护一下就行了。具体的就是在树上维护fa,然后记得按秩合并。。

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;int n,m;const int N=1e6;struct node{    int l,r,fa;}t[N*20];int a[N],size[N],root[N],rank[N],f[N],tot;int q,now;inline void build(int &x,int l,int r){    x=++tot;    if (l==r)    {        t[x].fa=l;        return;     }    int mid=(l+r)/2;    build(t[x].l,l,mid);    build(t[x].r,mid+1,r);}inline int find(int d,int l,int r,int x){    if (l==r)    {        if (t[d].fa==l)return l;        else return find(root[now],1,n,t[d].fa);    }    int mid=(l+r)/2;    if (x<=mid)return find(t[d].l,l,mid,x);    else return find(t[d].r,mid+1,r,x);}inline void modify(int &d,int p,int l,int r,int x,int y){    d=++tot;    t[d].l=t[p].l;    t[d].r=t[p].r;    if (l==r)    {        t[d].fa=y;        return;    }    int mid=(l+r)/2;    if (x<=mid)modify(t[d].l,t[p].l,l,mid,x,y);    else modify(t[d].r,t[p].r,mid+1,r,x,y);}int main(){    scanf("%d%d",&n,&q);    build(root[0],1,n);    int last=0;    fo(i,1,q)    {        now=i;        int op;        scanf("%d",&op);        root[i]=root[i-1];        if (op==1)        {            int x,y;            scanf("%d%d",&x,&y);            x^=last,y^=last;            int w=find(root[i],1,n,y),u=find(root[i],1,n,x);            if (w==u)continue;            if (size[w]>size[u])swap(w,u);            size[u]+=size[w];            modify(root[i],root[i-1],1,n,w,u);        }        else if (op==2)        {            int x;            scanf("%d",&x);            x^=last;            root[i]=root[x];        }        else if (op==3)        {            int x,y;            scanf("%d%d",&x,&y);            x^=last,y^=last;            if (find(root[i],1,n,y)==find(root[i],1,n,x))last=1;            else last=0;            printf("%d\n",last);        }    }    return 0;}
0 0
原创粉丝点击