首页 > 其他 > 详细

洛谷P3402 可持久化并查集

时间:2019-10-05 20:49:13      阅读:98      评论:0      收藏:0      [点我收藏+]

n个集合 m个操作

操作:

  • 1 a b 合并a,b所在集合

  • 2 k 回到第k次操作之后的状态(查询算作操作)

  • 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

说是可持久化并查集,实际上是把并查集的所有find和merge操作都放到可持久化数组上做,这样可以做到完全可持久化(不仅能查询某个历史版本,而且还能在某个历史版本的基础上进行修改)

注意并查集要按秩合并

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=2e5+10;
 4 int rt[N],fa[N*20],mxd[N*20],ls[N*20],rs[N*20],tot,n,m;
 5 #define mid ((l+r)>>1)
 6 int cpy(int v) {int u=++tot; fa[u]=fa[v],mxd[u]=mxd[v],ls[u]=ls[v],rs[u]=rs[v]; return u;}
 7 int getfa(int x,int u,int l=1,int r=n) {
 8     if(l==r)return fa[u];
 9     return x<=mid?getfa(x,ls[u],l,mid):getfa(x,rs[u],mid+1,r);
10 }
11 void upd(int* a,int p,int x,int v,int& u,int l=1,int r=n) {
12     u=cpy(v);
13     if(l==r) {a[u]=x; return;}
14     p<=mid?upd(a,p,x,ls[v],ls[u],l,mid):upd(a,p,x,rs[v],rs[u],mid+1,r);
15 }
16 int fd(int x,int u) {
17     int fx=getfa(x,u);
18     return fx?fd(fx,u):x;
19 }
20 void mg(int x,int y,int& u) {
21     int fx=fd(x,u),fy=fd(y,u);
22     if(fx==fy)return;
23     if(mxd[fx]>mxd[fy])swap(fx,fy);
24     upd(fa,fx,fy,u,u);
25     if(mxd[fx]==mxd[fy])upd(mxd,fy,mxd[fx]+1,u,u);
26 }
27 int main() {
28     mxd[0]=1;
29     scanf("%d%d",&n,&m);
30     for(int i=1; i<=m; ++i) {
31         rt[i]=rt[i-1];
32         int f,x,y;
33         scanf("%d",&f);
34         if(f==1)scanf("%d%d",&x,&y),mg(x,y,rt[i]);
35         else if(f==2)scanf("%d",&x),rt[i]=rt[x];
36         else scanf("%d%d",&x,&y),printf("%d\n",fd(x,rt[i])==fd(y,rt[i]));
37     }
38     return 0;
39 }

 

洛谷P3402 可持久化并查集

原文:https://www.cnblogs.com/asdfsag/p/11625627.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!