1. 程式人生 > >bzoj 3674: 可持久化並查集加強版

bzoj 3674: 可持久化並查集加強版

合並 struct 操作 logs void des 查詢 uil 出了

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: 可持久化並查集加強版