bzoj 3673&3674: 可持久化并查集 by zky

Description

n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

0<n,m<=2*10^4

Input

Output

Sample Input

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

Sample Output

1
0
1

 

题解:

首先普通并查集操作中,是靠fa这个数组维护的

所以要可持久并查集,就要可持久化fa数组,所以用到可持久化线段树维护.

注意要路径压缩

 

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #define RG register
 8 #define il inline
 9 using namespace std;
10 const int N=2000005,M=20005;
11 int gi(){
12     int str=0;char ch=getchar();
13     while(ch>'9' || ch<'0')ch=getchar();
14     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
15     return str;
16 }
17 int n,m,tot=0,root[M];
18 struct node{
19     int ls,rs,fa;
20 }t[N];
21 il void build(int &rt,int l,int r){
22     rt=++tot;
23     if(l==r){
24         t[rt].fa=l;
25         return ;
26     }
27     int mid=(l+r)>>1;
28     build(t[rt].ls,l,mid);build(t[rt].rs,mid+1,r);
29 }
30 il int query(int rt,int l,int r,int sa){
31     if(l==r)
32         return rt;
33     int mid=(l+r)>>1;
34     if(sa>mid)return query(t[rt].rs,mid+1,r,sa);
35     else return query(t[rt].ls,l,mid,sa);
36 }
37 il void updata(int &rt,int last,int l,int r,int sa,int to){
38     rt=++tot;t[rt]=t[last];
39     if(l==r){
40         t[rt].fa=to;
41         return ;
42     }
43     int mid=(l+r)>>1;
44   if(sa>mid)updata(t[rt].rs,t[last].rs,mid+1,r,sa,to);
45     else updata(t[rt].ls,t[last].ls,l,mid,sa,to);
46 }
47 il int find(int x,int i){
48     int c=query(root[i],1,n,x);
49     if(t[c].fa==x)return x;
50     int d=find(t[c].fa,i);
51     updata(root[i],root[i],1,n,x,d);
52     return d;
53 }
54 void work()
55 {
56     int flag,x,y,fx,fy;
57     n=gi();m=gi();
58     build(root[0],1,n);
59     for(int i=1;i<=m;i++){
60         flag=gi();x=gi();
61         if(flag==1){
62             y=gi();
63             root[i]=root[i-1];
64             fx=find(x,i);fy=find(y,i);
65             if(fx==fy)continue;
66             updata(root[i],root[i-1],1,n,fx,fy);
67         }
68         else if(flag==2)root[i]=root[x];
69         else{
70             y=gi();
71             root[i]=root[i-1];
72             fx=find(x,i);fy=find(y,i);
73             if(fx==fy)puts("1");
74             else puts("0");
75         }
76     }
77 }
78 
79 int main()
80 {
81     work();
82     return 0;
83 }

 

posted @ 2017-08-20 12:04  PIPIBoss  阅读(215)  评论(0编辑  收藏  举报