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
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 }