题目传送门

可持久化并查集

n个集合 m个操作

操作:

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

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

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

输入输出格式

输入格式:

输出格式:

输入输出样例

输入样例#1:

5 6
1 1 2
3 1 2
2 0
3 1 2
2 1
3 1 2
输出样例#1:

1
0
1

说明

$1 \le n \le 10^5, 1 \le m \le 2 \times 10^5$

By zky 出题人大神犇


  分析:

  解锁并查集的新姿势——可持久化并查集。

  其实大部分的可持久化数据结构都是可以由主席树和可持久化平衡树实现的,所以只要能把主席树理解透彻了,其他的也差不多就不难理解了。本体的关键在于用主席树维护并查集的$fa[]$数组,同时还要注意不能路径压缩,否则会挂的很惨。另外,为了保证时间复杂度,还需要采用按秩合并,$rk[]$数组同样用主席树维护。

  Code:

  

//It is made by HolseLee on 8th Aug 2018
//Luogu.org P3402
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#pragma GCC optimize(2)
using namespace std; const int N=1e5+;
int n,m,tot,fa[N*],rk[N*],root[N*];
struct Seg{
int ls,rs;
};
struct President{
Seg t[N*]; inline void build(int &rt,int l,int r)
{
rt=++tot;
if(l==r){
fa[rt]=l;return;
}
int mid=(l+r)>>;
build(t[rt].ls,l,mid);
build(t[rt].rs,mid+,r);
} inline void update(int &rt,int las,int l,int r,int pos,int f)
{
rt=++tot;t[rt].ls=t[las].ls,t[rt].rs=t[las].rs;
if(l==r){
fa[rt]=f;rk[rt]=rk[las];
return;
}
int mid=(l+r)>>;
if(pos<=mid)update(t[rt].ls,t[las].ls,l,mid,pos,f);
else update(t[rt].rs,t[las].rs,mid+,r,pos,f);
} inline int quary(int rt,int l,int r,int pos)
{
if(l==r)return rt;
int mid=(l+r)>>;
if(pos<=mid)return quary(t[rt].ls,l,mid,pos);
else return quary(t[rt].rs,mid+,r,pos);
} inline int find(int i,int x)
{
int f=quary(root[i],,n,x);
if(x==fa[f])return f;
return find(i,fa[f]);
} inline void pushup(int rt,int l,int r,int pos)
{
if(l==r){
rk[rt]++;
return;
}
int mid=(l+r)>>;
if(pos<=mid)pushup(t[rt].ls,l,mid,pos);
else pushup(t[rt].rs,mid+,r,pos);
}
}T; inline int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
} int main()
{
n=read();m=read();
T.build(root[],,n);
int op,x,y;
for(int i=;i<=m;++i){
op=read();
switch (op){
case : root[i]=root[i-];
x=read(),y=read();x=T.find(i,x),y=T.find(i,y);
if(fa[x]==fa[y])continue;
if(rk[x]>rk[y])swap(x,y);
T.update(root[i],root[i-],,n,fa[x],fa[y]);
if(rk[x]==rk[y])T.pushup(root[i],,n,fa[y]);
break; case :
x=read();root[i]=root[x];
break; case : root[i]=root[i-];
x=read(),y=read();x=T.find(i,x),y=T.find(i,y);
if(fa[x]==fa[y])printf("1\n");else printf("0\n");
break;
}
}
return ;
}

洛谷P3402 【模板】可持久化并查集 [主席树,并查集]的更多相关文章

  1. 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]

    题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...

  2. 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】

    题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...

  3. 洛谷.3834.[模板]可持久化线段树(主席树 静态区间第k小)

    题目链接 //离散化后范围1~cnt不要错 #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  4. 洛谷.3835.[模板]可持久化平衡树(fhq treap)

    题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...

  5. ☆ [洛谷P2633] Count on a tree 「树上主席树」

    题目类型:主席树+\(LCA\) 传送门:>Here< 题意:给出一棵树.每个节点有点权.问某一条路径上排名第\(K\)小的点权是多少 解题思路 类似区间第\(K\)小,但放在了树上. 考 ...

  6. 【洛谷 P2633】 Count on a tree(主席树,树上差分)

    题目链接 思维难度0 实现难度7 建出主席树后用两点的状态减去lca和lca父亲的状态,然后在新树上跑第\(k\)小 #include <cstdio> #include <cstr ...

  7. 洛谷$P$2468 粟粟的书架 $[SDOI2010]$ 主席树

    正解:主席树 解题报告: 传送门! 题目大意是说,给定一个矩形,然后每次会给一个,这个大矩形中的一个小矩形,询问从小矩形中最少选多少个数字能满足它们之和大于等于给定数字$x$ 看起来很神的样子,完全不 ...

  8. bzoj3673 & bzoj3674 & 洛谷P3402 可持久化并查集

    题目:bzoj3673:https://www.lydsy.com/JudgeOnline/problem.php?id=3673 bzoj3674:https://www.lydsy.com/Jud ...

  9. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

随机推荐

  1. Tensorflow Batch normalization函数

    Tensorflow Batch normalization函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 stackoverflow上tensorflow实现BN的不同函数的 ...

  2. tf.transpose函数解析

    tf.transpose函数解析 觉得有用的话,欢迎一起讨论相互学习~Follow Me tf.transpose(a, perm = None, name = 'transpose') 解释 将a进 ...

  3. 2015/9/21 Python基础(17):绑定和方法调用

    绑定和方法调用现在我们需要再次阐述Python中绑定(binding)的概念,它主要与方法调用相关联.方法是类内部定义的函数,这意味着方法是类属性而不是实例属性.其次,方法只有在其所属的类拥有实例时, ...

  4. 在asp.net 中生成PDF的方法

    近期要用asp.net 2.0生成PDF,看了下书,查了下资料,发现可以有组件帮得上忙,可以下载itextsharp(https://sourceforge.net/projects/itextsha ...

  5. 【BZOJ】3991: [SDOI2015]寻宝游戏 虚树+DFS序+set

    [题意]给定n个点的带边权树,对于树上存在的若干特殊点,要求任选一个点开始将所有特殊点走遍后返回.现在初始没有特殊点,m次操作每次增加或减少一个特殊点,求每次操作后的总代价.n,m<=10^5. ...

  6. Calf Flac

    1.3.3 Calf Flac Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 223  Solved: 42[Submit][Status][Forum] ...

  7. malloc原理和内存碎片【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3820852.html 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查 ...

  8. Python中如何Debug

    debug是编码是非常重要的调试技巧,通过在运行过程中设置断点,帮助开发人员更好的理解运行过程. Python中debug不像JAVA或者C++那样在IDE中设置断点那么直观. Python的debu ...

  9. [How to] MapReduce on HBase ----- 简单二级索引的实现

    1.简介 MapReduce计算框架是二代hadoop的YARN一部分,能够提供大数据量的平行批处理.MR只提供了基本的计算方法,之所以能够使用在不用的数据格式上包括HBase表上是因为特定格式上的数 ...

  10. ireport报表,打印时,报表加载失败的解决方法

    1.报表加载失败图示 2.解决方法 原创作者:DSHORE 作者主页:http://www.cnblogs.com/dshore123/ 原文出自:http://www.cnblogs.com/dsh ...