博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3673/3674:可持久化并查集
阅读量:7012 次
发布时间:2019-06-28

本文共 3132 字,大约阅读时间需要 10 分钟。

Description

n个集合 m个操作

操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

0<n,m<=2*10^4

Input

Output

Sample Input

5 6
1 1 2
3 1 2
2 0
3 1 2
2 1
3 1 2

Sample Output

1

0
1

Solution

板子题……只不过网上有很多假做法。

具体做法就是整两个可持久化数组(不知道谁起的这么鬼畜的名字……我还是更喜欢叫他可持久化线段树)来记录并查集的$fa$数组和$dep$数组。因为路径压缩会破坏可持久化的结构,所以我们只能记录$dep$数组来按秩合并。

网上很多只搞了一颗可持久化线段树,维护$fa$就可持久化线段树$insert$一条链,维护$dep$就修改历史版本上的点的做法是错的……已经被卡掉了QAQ

Code

1 #include
2 #include
3 #define N (200009) 4 using namespace std; 5 6 int n,m,lastans,opt,x,y; 7 8 struct Tree 9 {10 struct Sgt{
int ls,rs,v;}Segt[N*20];11 int sgt_num,a[N],Root[N];12 int Build(int l,int r)13 {14 int now=++sgt_num;15 if (l==r) {Segt[now].v=a[l]; return now;}16 int mid=(l+r)>>1;17 Segt[now].ls=Build(l,mid);18 Segt[now].rs=Build(mid+1,r);19 return now;20 }21 int Update(int pre,int l,int r,int x,int v)22 {23 int now=++sgt_num;24 Segt[now].ls=Segt[pre].ls;25 Segt[now].rs=Segt[pre].rs;26 if (l==r) {Segt[now].v=v; return now;}27 int mid=(l+r)>>1;28 if (x<=mid) Segt[now].ls=Update(Segt[now].ls,l,mid,x,v);29 else Segt[now].rs=Update(Segt[now].rs,mid+1,r,x,v);30 return now;31 }32 int Query(int now,int l,int r,int x)33 {34 if (l==r) return Segt[now].v;35 int mid=(l+r)>>1;36 if (x<=mid) return Query(Segt[now].ls,l,mid,x);37 else return Query(Segt[now].rs,mid+1,r,x);38 }39 }CT[2];40 41 int Find(int x,int t)42 {43 int fa=CT[0].Query(CT[0].Root[t],1,n,x);44 return x==fa?x:Find(fa,t);45 }46 47 int main()48 {49 scanf("%d%d",&n,&m);50 for (int i=1; i<=n; ++i)51 CT[0].a[i]=i, CT[1].a[i]=1;52 CT[0].Root[0]=CT[0].Build(1,n);53 CT[1].Root[0]=CT[1].Build(1,n);54 for (int i=1; i<=m; ++i)55 {56 scanf("%d",&opt);57 if (opt==1)58 {59 CT[0].Root[i]=CT[0].Root[i-1];60 CT[1].Root[i]=CT[1].Root[i-1];61 scanf("%d%d",&x,&y);62 /*x^=lastans; y^=lastans;*/63 int fx=Find(x,i),fy=Find(y,i);64 if (fx==fy) continue;65 int dfx=CT[1].Query(CT[1].Root[i],1,n,fx);66 int dfy=CT[1].Query(CT[1].Root[i],1,n,fy);67 if (dfx>dfy) swap(fx,fy);68 CT[0].Root[i]=CT[0].Update(CT[0].Root[i],1,n,fx,fy);69 if (dfx!=dfy) continue;70 CT[1].Root[i]=CT[1].Update(CT[1].Root[i],1,n,fy,dfy+1);71 }72 if (opt==2)73 {74 scanf("%d",&x); /*x^=lastans;*/75 CT[0].Root[i]=CT[0].Root[x];76 CT[1].Root[i]=CT[1].Root[x];77 }78 if (opt==3)79 {80 CT[0].Root[i]=CT[0].Root[i-1];81 CT[1].Root[i]=CT[1].Root[i-1];82 scanf("%d%d",&x,&y);83 /*x^=lastans; y^=lastans;*/84 int fx=Find(x,i),fy=Find(y,i);85 if (fx==fy) puts("1")/*, lastans=1*/;86 else puts("0")/*, lastans=0*/;87 }88 }89 }

转载于:https://www.cnblogs.com/refun/p/10230348.html

你可能感兴趣的文章
Laravel5做权限管理
查看>>
Spring 通过Java代码装配bean
查看>>
架构重构-好文分享
查看>>
使用shell批量生成数据整合式迁移的脚本
查看>>
[20151021]理解dbms_xplan.display_cursor的format参数all.txt
查看>>
Unicode字符编码标准
查看>>
云计算就像是产业链的重新组合
查看>>
第三代北斗芯片发布 2020年北斗计划向全球提供服务
查看>>
阿里巴巴集团CTO王坚:云计算让理想平等
查看>>
《中国人工智能学会通讯》——11.30 深度迁移学习
查看>>
Dell EMC扩充数据保护产品线 Data Domain增强云分层功能
查看>>
美柚社区精选:贴心宝妈的八大育儿经验
查看>>
走进医疗明星企业之北京天坛普华医院
查看>>
一点资讯电影贴片广告以假乱真
查看>>
曙光出炉“数据中国加速计划”
查看>>
中国制造2025新机遇 机器视觉行业爆发
查看>>
中国工商银行阿根廷分行用数据运营展现本地特色
查看>>
使用闪存存储的优势与注意事项
查看>>
网络钓鱼防不胜防:大型科技公司竟被骗逾1亿美元
查看>>
网络间谍活动月光迷宫已演变成Turla
查看>>