3674: 可持久化并查集加强版
Submit: 3592 Solved: 1337
[Submit][Status][Discuss]
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
1 1 2
3 1 2
2 1
3 0 3
2 1
3 1 2
Sample Output
1
0
1
0
1
HINT
Source
rope大法好!!!!。
有了rope,
主席树什么的都可以靠边站了,
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<ext/rope> 7 using namespace std; 8 using namespace __gnu_cxx; 9 const int MAXN=2000050; 10 const int maxn=0x7fffffff; 11 void read(int &n) 12 { 13 char c='+';int x=0;bool flag=0; 14 while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} 15 while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();} 16 flag==1?n=-x:n=x; 17 } 18 19 rope<int> *rp[MAXN]; 20 int a[MAXN]; 21 int n,m,how,x,y,lastans; 22 int find(int i,int x) 23 { 24 if(rp[i]->at(x)==x) return x; 25 int f=find(i,rp[i]->at(x)); 26 if(f==rp[i]->at(x)) return f; 27 rp[i]->replace(x,f); 28 return f; 29 } 30 void merge(int i,int x,int y) 31 { 32 x=find(i,x),y=find(i,y); 33 if(x!=y) rp[i]->replace(y,x); 34 } 35 int main() 36 { 37 int n,m; 38 read(n);read(m); 39 for(int i=1;i<=n;i++) a[i]=i; 40 rp[0]=new rope<int> (a,a+n+1); 41 for(int i=1;i<=m;i++) 42 { 43 rp[i]=new rope<int> (*rp[i-1]); 44 int how;read(how); 45 if(how==1) 46 { 47 read(x);read(y); 48 merge(i,x^lastans,y^lastans); 49 } 50 else if(how==2) 51 { 52 read(x); 53 rp[i]=rp[x^lastans]; 54 } 55 else if(how==3) 56 { 57 read(x);read(y); 58 printf("%d\n",lastans=(find(i,x^lastans)==find(i,y^lastans))); 59 } 60 } 61 return 0; 62 }
作者:自为风月马前卒
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。