BZOJ3673/3674:可持久化并查集
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
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
#include<iostream>
#include<cstdio>
#define N (200009)
using namespace std; int n,m,lastans,opt,x,y; struct Tree
{
struct Sgt{int ls,rs,v;}Segt[N*];
int sgt_num,a[N],Root[N];
int Build(int l,int r)
{
int now=++sgt_num;
if (l==r) {Segt[now].v=a[l]; return now;}
int mid=(l+r)>>;
Segt[now].ls=Build(l,mid);
Segt[now].rs=Build(mid+,r);
return now;
}
int Update(int pre,int l,int r,int x,int v)
{
int now=++sgt_num;
Segt[now].ls=Segt[pre].ls;
Segt[now].rs=Segt[pre].rs;
if (l==r) {Segt[now].v=v; return now;}
int mid=(l+r)>>;
if (x<=mid) Segt[now].ls=Update(Segt[now].ls,l,mid,x,v);
else Segt[now].rs=Update(Segt[now].rs,mid+,r,x,v);
return now;
}
int Query(int now,int l,int r,int x)
{
if (l==r) return Segt[now].v;
int mid=(l+r)>>;
if (x<=mid) return Query(Segt[now].ls,l,mid,x);
else return Query(Segt[now].rs,mid+,r,x);
}
}CT[]; int Find(int x,int t)
{
int fa=CT[].Query(CT[].Root[t],,n,x);
return x==fa?x:Find(fa,t);
} int main()
{
scanf("%d%d",&n,&m);
for (int i=; i<=n; ++i)
CT[].a[i]=i, CT[].a[i]=;
CT[].Root[]=CT[].Build(,n);
CT[].Root[]=CT[].Build(,n);
for (int i=; i<=m; ++i)
{
scanf("%d",&opt);
if (opt==)
{
CT[].Root[i]=CT[].Root[i-];
CT[].Root[i]=CT[].Root[i-];
scanf("%d%d",&x,&y);
/*x^=lastans; y^=lastans;*/
int fx=Find(x,i),fy=Find(y,i);
if (fx==fy) continue;
int dfx=CT[].Query(CT[].Root[i],,n,fx);
int dfy=CT[].Query(CT[].Root[i],,n,fy);
if (dfx>dfy) swap(fx,fy);
CT[].Root[i]=CT[].Update(CT[].Root[i],,n,fx,fy);
if (dfx!=dfy) continue;
CT[].Root[i]=CT[].Update(CT[].Root[i],,n,fy,dfy+);
}
if (opt==)
{
scanf("%d",&x); /*x^=lastans;*/
CT[].Root[i]=CT[].Root[x];
CT[].Root[i]=CT[].Root[x];
}
if (opt==)
{
CT[].Root[i]=CT[].Root[i-];
CT[].Root[i]=CT[].Root[i-];
scanf("%d%d",&x,&y);
/*x^=lastans; y^=lastans;*/
int fx=Find(x,i),fy=Find(y,i);
if (fx==fy) puts("")/*, lastans=1*/;
else puts("")/*, lastans=0*/;
}
}
}
BZOJ3673/3674:可持久化并查集的更多相关文章
- [BZOJ3673&3674]可持久化并查集&加强版
题目大意:让你实现一个可持久化的并查集(3674强制在线). 解题思路:刚刚介绍了一个叫rope的神器:我是刘邦,在这两题(实际上两题没什么区别)就派上用场了. 正解应该是主席树||可持久化平衡树,然 ...
- [bzoj3673/3674可持久化并查集加强版]
n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2 ...
- BZOJ 3674 可持久化并查集加强版(路径压缩版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
- BZOJ 3674 可持久化并查集加强版(按秩合并版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
- 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- bzoj 3673&3674 可持久化并查集&加强版(可持久化线段树+启发式合并)
CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...
- BZOJ 3674 可持久化并查集加强版(主席树变形)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [Submit][Sta ...
- bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)
Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...
- [bzoj] 3673 3674 可持久化并查集 || 可持久化数组
原题 加强版 题意: 可持久化并查集模板-- 题解: 用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态. 不能用路径压缩,但是要按置合并,使复杂度保证在O(log) #include&l ...
随机推荐
- Android获取SD卡总容量,可用大小,机身内存总容量及可用大小
public long getSDTotalSize() { /*获取存储卡路径*/ File sdcardDir= Environment.getExternalStorageDirectory() ...
- 网页中通过js修改img的src属性刷新图片时,图片缓存问题现象表述及问题解决【ps:引用大神案例http://blog.csdn.net/goodleiwei/article/details/50737548】
问题:上传一张图片,通过js更新src属性刷新图片使其即时显示时, 当img的src当前的url与上次地址无变化时(只更改图片,名称不变,不同图片名称相同)图片不变化(仍显示原来的图片) 但通过fir ...
- Killing Monsters(hdu4970)
Killing Monsters Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- Map集合框架的练习
Map是一个很重要的集合框架,它以键值对的方式存储,下面是一个Map集合的小练习,使用了keySet的取出方法. 取出字符串的每一个字符,记录每一个字母出现的次数.使用Map集合框架. package ...
- 图片链接转成base64
一半需要我的图像转换为base64字符串,这样我们可以把我的形象到服务器.现在我们提供一个js: function convertImgToBase64(url, callback, outputFo ...
- Gruntfile.js文件配置项
GRUNT安装与配置 Posted on 2016-08-19 18:13 听风吹来的种子 阅读(47) 评论(0) 编辑 收藏 安装 CLI npm install -g grunt-cli//全局 ...
- drupal 去掉视图中字段默认的HTML标签
1.格式--设置 去掉复选框 2.具体字段:
- 关于Mysql数据库的知识总结
2017年6月8日,天气阴.心情晴. 连续做梦两个晚上了,昨晚竟然梦见一个很长时间不联系的初中同学了,早上上班的路上聊了聊.女孩现在出差在贵州,风景秀美的地方.我说“你现在生活很滋润”.女孩说“那是你 ...
- MariaDB MySQL变量取值避免四舍五入的方法
MySQL变量取值避免四舍五入的方法 By:授客 QQ:1033553122 在一些对数据精确度要求比较高的场景(比如资金结算)下,变量取值时不能对变量值进行四舍五入操作,这时候就要做些预处理工作. ...
- Cobalt Strike 学习
前言 本文以一个模拟的域环境为例对 Cobalt Strike 的使用实践一波. 环境拓扑图如下: 攻击者(kali) 位于 192.168.245.0/24 网段,域环境位于 192.168.31. ...