BZOJ 3674 可持久化并查集加强版(按秩合并版本)

  1 /*
  2 bzoj 3674: 可持久化并查集加强版
  3 http://www.lydsy.com/JudgeOnline/problem.php?id=3674
  4 用可持久化线段树维护可持久化数组从而实现可持久化并查集
  5 可持久化线段树+并查集+按秩合并+读入优化
  6 */
  7 #include <cstdio>
  8 #include <algorithm>
  9 using namespace std;
 10 const int Nmax=200005;
 11 int root_fa[Nmax],root_rankk[Nmax];
 12 
 13 inline int read()
 14 {
 15     int x=0;char ch=getchar();
 16     while(ch>'9'||ch<'0')ch=getchar();
 17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 18     return x;
 19 }
 20 struct Node
 21 {
 22     int ls;
 23     int rs;
 24     int data;
 25 };
 26 Node fa[40*Nmax];
 27 Node rankk[40*Nmax];
 28 int n,m,ans,a,b,k;
 29 int size_fa,size_rankk;
 30 
 31 void build_rankk(int &root,int l,int r)
 32 {
 33     root=size_rankk++;
 34     int mid=(l+r)>>1;
 35     if(l==r)
 36     {
 37         rankk[root].data=0;
 38         return;
 39     }
 40     build_rankk(rankk[root].ls,l,mid);
 41     build_rankk(rankk[root].rs,mid+1,r);
 42 }
 43 
 44 void insert_rankk(int last,int &root,int pos,int l,int r)
 45 {
 46     rankk[size_rankk]=rankk[last];
 47     root=size_rankk;
 48     size_rankk++;
 49     if(rankk[root].ls==rankk[root].rs)
 50     {
 51         rankk[root].data++;
 52         return;
 53     }
 54     int mid=(l+r)>>1;
 55     if(pos<=mid)
 56         insert_rankk(rankk[last].ls,rankk[root].ls,pos,l,mid);    
 57     else
 58         insert_rankk(rankk[last].rs,rankk[root].rs,pos,mid+1,r);
 59 }
 60 
 61 int search_rankk(int root,int pos,int l,int r)
 62 {
 63     if(rankk[root].ls==rankk[root].rs)
 64         return rankk[root].data;
 65     int mid=(l+r)>>1;
 66     if(pos<=mid)
 67         return search_rankk(rankk[root].ls,pos,l,mid);    
 68     else
 69         return search_rankk(rankk[root].rs,pos,mid+1,r);
 70 }
 71 
 72 void build_fa(int &root,int l,int r)
 73 {
 74     root=size_fa++;
 75     int mid=(l+r)>>1;
 76     if(l==r)
 77     {
 78         fa[root].data=l;
 79         return;
 80     }
 81     build_fa(fa[root].ls,l,mid);
 82     build_fa(fa[root].rs,mid+1,r);
 83 }
 84 
 85 void insert_fa(int last,int &root,int pos,int data,int l,int r)
 86 {
 87     fa[size_fa]=fa[last];
 88     root=size_fa;
 89     size_fa++;
 90     if(fa[root].ls==fa[root].rs)
 91     {
 92         // printf("root:%d,l:%d,data:%d
",root,fa[root].l,data);
 93         fa[root].data=data;
 94         return;
 95     }
 96     int mid=(l+r)>>1;
 97     if(pos<=mid)
 98         insert_fa(fa[last].ls,fa[root].ls,pos,data,l,mid);    
 99     else
100         insert_fa(fa[last].rs,fa[root].rs,pos,data,mid+1,r);
101 }
102 
103 int search_fa(int root,int pos,int l,int r)
104 {
105     if(fa[root].ls==fa[root].rs)
106         return fa[root].data;
107     int mid=(l+r)>>1;
108     if(pos<=mid)
109         return search_fa(fa[root].ls,pos,l,mid);    
110     else
111         return search_fa(fa[root].rs,pos,mid+1,r);
112 }
113 
114 int find(int root,int x)
115 {
116     // if(x==0)
117     //     printf("error!!!!
");
118     int fa=search_fa(root,x,1,n);
119     if(fa!=x)
120         return find(root,fa);
121     else
122         return fa;
123 }
124 
125 // void watch(int root,int l,int r)
126 // {
127 //     printf("tree[%d].l=%d,tree[%d].r=%d,tree[%d].data=%d
",root,fa[root].l,root,fa[root].r,root,fa[root].data);    
128 //     if(l==r)
129 //         return;
130 //     int mid=(l+r)>>1;
131 //     watch(fa[root].ls,l,mid);
132 //     watch(fa[root].rs,mid+1,r);
133 // }
134 
135 int main()
136 {
137     freopen("bzoj3674.in","r",stdin);
138     //scanf("%d%d",&n,&m);
139     n=read();
140     m=read();
141     ans=0;
142     int q;
143     build_fa(root_fa[0],1,n);
144     build_rankk(root_rankk[0],1,n);
145     // printf("the 0 watch:
");
146     //     watch(root_fa[0],1,n);
147     for(int i=1;i<=m;i++)
148     {
149         //scanf("%d",&q);
150         q=read();
151         if(q==1)
152         {
153             a=read();
154             b=read();
155             // scanf("%d%d",&a,&b);
156             a^=ans;b^=ans;
157             int rt1=find(root_fa[i-1],a),rt2=find(root_fa[i-1],b);
158             // printf("root[%d]=%d,root[%d]=%d
",a,rt1,b,rt2);
159             if(rt1==rt2)
160             {
161                 root_fa[i]=root_fa[i-1];
162                 root_rankk[i]=root_rankk[i-1];
163             }
164             else
165             {
166                 int rk1=search_rankk(root_rankk[i-1],rt1,1,n),rk2=search_rankk(root_rankk[i-1],rt2,1,n);
167                 if(rk1<rk2)
168                 {
169                     insert_fa(root_fa[i-1],root_fa[i],rt1,rt2,1,n);
170                     root_rankk[i]=root_rankk[i-1];
171                 }
172                 else
173                 {
174                     insert_fa(root_fa[i-1],root_fa[i],rt2,rt1,1,n);
175                     if(rk1==rk2) 
176                         insert_rankk(root_rankk[i-1],root_rankk[i],rt1,1,n);
177                     else
178                         root_rankk[i]=root_rankk[i-1];
179                 }
180             }
181             // printf("search_fa[2]=%d
",search_fa(root_fa[1],2) );
182             // printf("root[%d]=%d,root[%d]=%d
",a,find(root_fa[i],a),b,find(root_fa[i],b));
183         }
184         else if(q==2)
185         {
186             k=read();
187             // scanf("%d",&k);
188             k^=ans;
189             root_fa[i]=root_fa[k];
190             root_rankk[i]=root_rankk[k];
191         }
192         else if(q==3)
193         {
194             a=read();
195             b=read();
196             // scanf("%d%d",&a,&b);
197             root_fa[i]=root_fa[i-1];
198             root_rankk[i]=root_rankk[i-1];
199             a^=ans;
200             b^=ans;
201             if(find(root_fa[i],a)==find(root_fa[i],b))
202                 ans=1;
203             else
204                 ans=0;
205             printf("%d
",ans);
206         }
207         //insert_fa(root_fa[i-1],root_fa[i],2,3);
208         // printf("root_fa[%d]:%d
",i,root_fa[i]);
209         // printf("the %d watch:
",i);
210         // watch(root_fa[i],1,n);
211     }
212     return 0;
213 }
原文地址:https://www.cnblogs.com/BBBob/p/6522825.html