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

 #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:可持久化并查集的更多相关文章

  1. [BZOJ3673&3674]可持久化并查集&加强版

    题目大意:让你实现一个可持久化的并查集(3674强制在线). 解题思路:刚刚介绍了一个叫rope的神器:我是刘邦,在这两题(实际上两题没什么区别)就派上用场了. 正解应该是主席树||可持久化平衡树,然 ...

  2. [bzoj3673/3674可持久化并查集加强版]

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

  3. BZOJ 3674 可持久化并查集加强版(路径压缩版本)

    /* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...

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

    /* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...

  5. 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  6. bzoj 3673&3674 可持久化并查集&加强版(可持久化线段树+启发式合并)

    CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...

  7. BZOJ 3674 可持久化并查集加强版(主席树变形)

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 2515  Solved: 1107 [Submit][Sta ...

  8. bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)

    Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...

  9. [bzoj] 3673 3674 可持久化并查集 || 可持久化数组

    原题 加强版 题意: 可持久化并查集模板-- 题解: 用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态. 不能用路径压缩,但是要按置合并,使复杂度保证在O(log) #include&l ...

随机推荐

  1. Android获取SD卡总容量,可用大小,机身内存总容量及可用大小

    public long getSDTotalSize() { /*获取存储卡路径*/ File sdcardDir= Environment.getExternalStorageDirectory() ...

  2. 网页中通过js修改img的src属性刷新图片时,图片缓存问题现象表述及问题解决【ps:引用大神案例http://blog.csdn.net/goodleiwei/article/details/50737548】

    问题:上传一张图片,通过js更新src属性刷新图片使其即时显示时, 当img的src当前的url与上次地址无变化时(只更改图片,名称不变,不同图片名称相同)图片不变化(仍显示原来的图片) 但通过fir ...

  3. Killing Monsters(hdu4970)

    Killing Monsters Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...

  4. Map集合框架的练习

    Map是一个很重要的集合框架,它以键值对的方式存储,下面是一个Map集合的小练习,使用了keySet的取出方法. 取出字符串的每一个字符,记录每一个字母出现的次数.使用Map集合框架. package ...

  5. 图片链接转成base64

    一半需要我的图像转换为base64字符串,这样我们可以把我的形象到服务器.现在我们提供一个js: function convertImgToBase64(url, callback, outputFo ...

  6. Gruntfile.js文件配置项

    GRUNT安装与配置 Posted on 2016-08-19 18:13 听风吹来的种子 阅读(47) 评论(0) 编辑 收藏 安装 CLI npm install -g grunt-cli//全局 ...

  7. drupal 去掉视图中字段默认的HTML标签

    1.格式--设置 去掉复选框 2.具体字段:

  8. 关于Mysql数据库的知识总结

    2017年6月8日,天气阴.心情晴. 连续做梦两个晚上了,昨晚竟然梦见一个很长时间不联系的初中同学了,早上上班的路上聊了聊.女孩现在出差在贵州,风景秀美的地方.我说“你现在生活很滋润”.女孩说“那是你 ...

  9. MariaDB MySQL变量取值避免四舍五入的方法

    MySQL变量取值避免四舍五入的方法 By:授客 QQ:1033553122 在一些对数据精确度要求比较高的场景(比如资金结算)下,变量取值时不能对变量值进行四舍五入操作,这时候就要做些预处理工作. ...

  10. Cobalt Strike 学习

    前言 本文以一个模拟的域环境为例对 Cobalt Strike 的使用实践一波. 环境拓扑图如下: 攻击者(kali) 位于 192.168.245.0/24 网段,域环境位于 192.168.31. ...