[BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky

思路:

用主席树维护并查集森林,每次连接时新增结点。
似乎并不需要启发式合并,我随随便便写了一个就跑到了3674第一页?
3673是这题的弱化版,本来写个暴力就能过,现在借用加强版的代码(去掉异或),直接吊打暴力程序。

 

 1 #include<cstdio>
 2 #include<cctype>
 3 inline int getint() {
 4     register char ch;
 5     while(!isdigit(ch=getchar()));
 6     register int x=ch^'0';
 7     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
 8     return x;
 9 }
10 const int N=200001,SIZE=3850000;
11 class PresistentDisjointSet {
12     private:
13         unsigned int left[SIZE],right[SIZE],sz;
14         int anc[SIZE];
15         unsigned int newnode() {
16             return sz++;
17         }
18         unsigned int getpos(const unsigned int p,const int b,const int e,const int x) {
19             if(b==e) return p;
20             int mid=(b+e)>>1;
21             return (x<=mid)?getpos(left[p],b,mid,x):getpos(right[p],mid+1,e,x);
22         }
23     public:
24         unsigned int root[N];
25         PresistentDisjointSet() {
26             sz=0;
27         }
28         void Build(unsigned int &p,const int b,const int e) {
29             p=newnode();
30             if(b==e) {
31                 anc[p]=b;
32                 return;
33             }
34             int mid=(b+e)>>1;
35             Build(left[p],b,mid);
36             Build(right[p],mid+1,e);
37         }
38         unsigned int find(const unsigned int p,const int b,const int e,const int x) {
39             int q=getpos(p,b,e,x);
40             return x==anc[q]?q:find(p,b,e,anc[q]);
41         }
42         unsigned int Union2(const unsigned int p,const int b,const int e,const int x,const int y) {
43             unsigned int new_p=newnode();
44             if(b==e) {
45                 anc[new_p]=y;
46                 return new_p;
47             }
48             int mid=(b+e)>>1;
49             if(x<=mid) left[new_p]=Union2(left[p],b,mid,x,y),right[new_p]=right[p];
50             if(x>mid) right[new_p]=Union2(right[p],mid+1,e,x,y),left[new_p]=left[p];
51             return new_p;
52         }
53         bool isConnected(const int x,const int y) {
54             return anc[x]==anc[y];
55         }
56         unsigned int Union(const unsigned int p,const int b,const int e,int x,int y) {
57             x=find(p,b,e,x),y=find(p,b,e,y);
58             if(isConnected(x,y)) return p;
59             return Union2(p,b,e,anc[x],anc[y]);
60         }
61 };
62 PresistentDisjointSet s;
63 int main() {
64     int n=getint(),lastans=0;
65     s.Build(s.root[0],1,n);
66     int m=getint();
67     for(register int i=1;i<=m;i++) {
68         int op=getint();
69         if(op==1) s.root[i]=s.Union(s.root[i-1],1,n,getint()^lastans,getint()^lastans);
70         else if(op==2) s.root[i]=s.root[getint()^lastans];
71         else s.root[i]=s.root[i-1],printf("%d\n",lastans=s.isConnected(s.find(s.root[i],1,n,getint()^lastans),s.find(s.root[i],1,n,getint()^lastans)));
72     }
73     return 0;
74 }

 

posted @ 2017-07-14 18:34  skylee03  阅读(142)  评论(0编辑  收藏  举报