bzoj 3674: 可持久化并查集加强版

Description

Description:
自从zkysb出了可持久化并查集后……
hzwer:乱写能AC,暴力踩标程
KuribohG:我不路径压缩就过了!
ndsf:暴力就可以轻松虐!
zky:……

n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
请注意本题采用强制在线,所给的a,b,k均经过加密,加密方法为x = x xor lastans,lastans的初始值为0
0<n,m<=2*10^5


Input

Output

Sample Input

5 6
1 1 2
3 1 2
2 1
3 0 3
2 1
3 1 2

Sample Output

1
0
1

可持久化并查集

就是用线段树维护每个点的父亲,其他都和主席树一样

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 using namespace std;
  6 struct Node
  7 {
  8   Node* ch[2];
  9   int fa; 
 10 }S[6000005],*pos=S,*root[200005];
 11 int n,m;
 12 int gi()
 13 {
 14   char ch=getchar();
 15   int x=0,flag=1;
 16   while (ch<'0'||ch>'9') 
 17     {if (ch=='-') flag=-1;ch=getchar();}
 18   while (ch>='0'&&ch<='9') 
 19     {
 20       x=(x>>3)+(x>>1)+ch-'0';
 21       ch=getchar();
 22     } 
 23   return x*flag;
 24 }
 25 void build(Node* &rt,int l,int r)
 26 {
 27   rt=++pos;
 28   if (l==r) 
 29     {
 30       return;
 31     }
 32   int mid=(l+r)>>1;
 33   build(rt->ch[0],l,mid);
 34   build(rt->ch[1],mid+1,r);
 35 }
 36 int query(Node* rt,int l,int r,int x)
 37 {
 38   if (l==r)
 39     {
 40       return rt->fa; 
 41     }
 42   int mid=(l+r)>>1;
 43   if (x<=mid) return query(rt->ch[0],l,mid,x);
 44   else return query(rt->ch[1],mid+1,r,x);
 45 }
 46 void update(Node* &rt,int l,int r,int x,int d)
 47 {
 48   Node* t=rt;
 49   rt=++pos;
 50   if (l==r)
 51     {
 52       rt->fa=d;
 53       return;
 54     }
 55   rt->ch[0]=t->ch[0];
 56   rt->ch[1]=t->ch[1];
 57   int mid=(l+r)>>1;
 58   if (x<=mid) update(rt->ch[0],l,mid,x,d);
 59   else update(rt->ch[1],mid+1,r,x,d);
 60 }
 61 int find(Node* rt,int x)
 62 {
 63   while (1)
 64     {
 65       int tmp=query(rt,1,n,x);
 66       if (tmp==0) return x;
 67       else x=tmp; 
 68     }
 69 }
 70 int main()
 71 {int i,a,b,lastans=0,opt;
 72   cin>>n>>m;
 73   build(root[0],1,n);
 74   for (i=1;i<=m;i++)
 75     {
 76       opt=gi();
 77       if (opt==1)
 78     {
 79       root[i]=root[i-1];
 80       a=gi();b=gi();
 81       a^=lastans;b^=lastans;
 82       int p=find(root[i],a);
 83       int q=find(root[i],b);
 84       if (p!=q)
 85         {
 86           update(root[i],1,n,q,p);
 87         }
 88     }
 89       else if (opt==2)
 90     {
 91       a=gi();
 92       a^=lastans;
 93       root[i]=root[a];
 94     }
 95       else if (opt==3)
 96     {
 97       root[i]=root[i-1];
 98       a=gi();b=gi();
 99       a^=lastans;b^=lastans;
100       int p=find(root[i],a);
101       int q=find(root[i],b);
102       if (p==q) printf("1\n"),lastans=1;
103       else printf("0\n"),lastans=0;
104     }
105     }
106 }

 

posted @ 2017-10-06 18:22  Z-Y-Y-S  阅读(224)  评论(0编辑  收藏  举报