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

Posted Z-Y-Y-S

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于bzoj 3674: 可持久化并查集加强版的主要内容,如果未能解决你的问题,请参考以下文章

[题解] bzoj 3674 可持久化并查集加强版

[BZOJ 3674]可持久化并查集加强版

可持久化并查集加强版 BZOJ 3674

bzoj3674 可持久化并查集加强版

BZOJ 3674 可持久化并查集加强版(主席树变形)

[BZOJ 3674]可持久化并查集加强版