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

时间:2019-09-03
本文章向大家介绍bzoj 3674: 可持久化并查集加强版,主要包括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
 
类似3673。 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 using namespace std;
 6 int son[4000010][2],par[4000010],cnt;
 7 void build(int &x,int l,int r)
 8 {
 9     x=++cnt;
10     if(l==r)
11     {
12         par[x]=l;
13         return;
14     }
15     int mid=(l+r)>>1;
16     build(son[x][0],l,mid);
17     build(son[x][1],mid+1,r);
18 }
19 void update(int &x,int l,int r,int p,int v)
20 {
21     cnt++;
22     son[cnt][0]=son[x][0];
23     son[cnt][1]=son[x][1];
24     x=cnt;
25     if(l==r)
26     {
27         par[x]=v;
28         return;
29     }
30     int mid=(l+r)>>1;
31     if(p<=mid)update(son[x][0],l,mid,p,v);
32     else update(son[x][1],mid+1,r,p,v);
33 }
34 int getpar(int x,int l,int r,int p)
35 {
36     if(l==r)return par[x];
37     int mid=(l+r)>>1;
38     if(p<=mid)return getpar(son[x][0],l,mid,p);
39     else return getpar(son[x][1],mid+1,r,p);
40 }
41 int root[200010];
42 int n,m;
43 pair<int,int> getrot(int k,int x)
44 {
45     int y;
46     int rnk=0;
47     while((y=getpar(root[k],1,n,x))!=x)rnk++,x=y;
48     return make_pair(x,rnk);
49 }
50 int ans;
51 int main()
52 {
53     scanf("%d%d",&n,&m);
54     build(root[0],1,n);
55     for(int i=1;i<=m;i++)
56     {
57         int op;
58         scanf("%d",&op);
59         if(op==2)
60         {
61             int k;
62             scanf("%d",&k);
63             k^=ans;
64             root[i]=root[k];
65         }
66         else
67         {
68             root[i]=root[i-1];
69             int a,b;
70             scanf("%d%d",&a,&b);
71             a^=ans;b^=ans;
72             pair<int,int>ta=getrot(i-1,a),tb=getrot(i-1,b);
73             a=ta.first;b=tb.first;
74             if(op==1)
75             {
76                 int ra=ta.second,rb=tb.second;
77                 if(a!=b)
78                 {
79                     if(ra<rb)update(root[i],1,n,a,b);
80                     else update(root[i],1,n,b,a);
81                 }
82             }
83             else
84             {
85                 if(a==b)ans=1;else ans=0;
86                 printf("%d\n",ans);
87             }
88         }
89     }
90     return 0;
91 }
View Code

原文地址:https://www.cnblogs.com/ZJXXCN/p/11455242.html