当前位置: 首页 > news >正文

【bzoj3673】可持久化并查集 by zky

Time Limit: 5 Sec Memory Limit: 128 MB

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

 

用可持久化线段树来可持久化数组以达到可持久化并查集的作用,有点像绕口令。。。

要注意的就是并查集的find也要在树上找到那个位置,使用它的位置,所以复杂度应该是两个log的,n logn logn 一次AC

 1 #include<bits/stdc++.h>
 2 #define maxn 20005
 3 #define mae 800005
 4 using namespace std;
 5 int n,m,root[maxn],l[mae],r[mae],cnt,fa[mae],rank[mae],L[mae],R[mae];
 6 void build(int& k,int le,int ri){
 7     if(!k) k=++cnt;L[k]=le;R[k]=ri;
 8     if(le==ri){fa[k]=le;rank[k]=0;return;}
 9     int mid=le+ri>>1;
10     build(l[k],le,mid);build(r[k],mid+1,ri);
11 }
12 void newly(int &k,int wi,int f,int h){
13     k=++cnt;
14     L[k]=L[wi];R[k]=R[wi];
15     if(L[k]==R[k]){fa[k]=h;return;}
16     l[k]=l[wi];r[k]=r[wi];
17     int mid=L[k]+R[k]>>1;
18     if(f<=mid) newly(l[k],l[wi],f,h);
19     else newly(r[k],r[wi],f,h);
20 }
21 int find(int k,int x){
22     if(L[k]==R[k]) return k;
23     int mid=L[k]+R[k]>>1;
24     if(x<=mid) return find(l[k],x);
25     else return find(r[k],x);
26 }
27 int fi(int x,int k){
28     k=find(root[x],k);
29     if(fa[k]!=L[k]) return fi(x,fa[k]);
30     return fa[k];
31 }
32 int main(){
33     scanf("%d%d",&n,&m);
34     build(root[0],1,n);int a,b,c,f,h;
35     for(int i=1;i<=m;i++){
36         scanf("%d",&a);
37         if(a==1){
38             scanf("%d%d",&b,&c);
39             f=fi(i-1,b);h=fi(i-1,c);
40             if(rank[f]<rank[h]) newly(root[i],root[i-1],f,h);
41             else{
42                 if(rank[f]>rank[h]) newly(root[i],root[i-1],h,f);
43                 else {newly(root[i],root[i-1],f,h);rank[find(root[i],f)]++;}
44             }
45         }
46         if(a==2) scanf("%d",&b),root[i]=root[b];
47         if(a==3){
48             scanf("%d%d",&b,&c);root[i]=root[i-1];
49             f=fi(i,b);h=fi(i,c);
50             if(f==h) printf("1\n");
51             else printf("0\n");
52         }
53     }
54     return 0;
55 }

 

转载于:https://www.cnblogs.com/awipppp/p/5959517.html

相关文章:

  • HashSet序列化问题
  • QT学习之路--菜单、工具条、状态栏
  • 序列化-理解readResolve()
  • Java thread的Interrupt, isInterrupt, interrupted
  • Java字符串
  • Java集合的Stack、Queue、Map的遍历
  • Java正则表达式应用总结
  • javascript的基础知识整理
  • 运行Java应用必须通过main()方法吗?
  • struts2标签库详解
  • Servlet技术总结
  • 深入研究servlet的线程安全问题
  • win10下 Edge和IE浏览器都不能上网,而其他浏览器可以。怎么办?
  • Servlet过滤器机制分析及应用
  • MySQL: Table 'mysql.plugin' doesn't exist的解决
  • 230. Kth Smallest Element in a BST
  • Android Studio:GIT提交项目到远程仓库
  • canvas绘制圆角头像
  • Druid 在有赞的实践
  • java概述
  • Python爬虫--- 1.3 BS4库的解析器
  • SpiderData 2019年2月16日 DApp数据排行榜
  • tab.js分享及浏览器兼容性问题汇总
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • Vue2 SSR 的优化之旅
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 复习Javascript专题(四):js中的深浅拷贝
  • 给第三方使用接口的 URL 签名实现
  • 技术胖1-4季视频复习— (看视频笔记)
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 消息队列系列二(IOT中消息队列的应用)
  • 应用生命周期终极 DevOps 工具包
  • 硬币翻转问题,区间操作
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 第二十章:异步和文件I/O.(二十三)
  • ​如何在iOS手机上查看应用日志
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (1)常见O(n^2)排序算法解析
  • (2)STM32单片机上位机
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (libusb) usb口自动刷新
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (二)换源+apt-get基础配置+搜狗拼音
  • (三分钟)速览传统边缘检测算子
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (转载)Linux 多线程条件变量同步
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • /bin/rm: 参数列表过长"的解决办法
  • @Bean有哪些属性