Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)
3673: 可持久化并查集 by zky
Time Limit: 5 Sec Memory Limit: 128 MB
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
HINT
Source
出题人大SB
/*
可持久化线段树+启发式合并.
可持久化线段树维护当前状态下集合的关系和秩的信息.
所谓的秩就是以该元素为代表元的所有元素中的最大深度.
然后按秩合并的目的是为了降常.
每个叶节点维护一颗线段树
合并的时候在权值线段树的子节点加一个数,
相当于连了一条边 表示有关系存在.
要先查询要将合并两个元素的父亲所在位置.
显然只有在两个集合秩相同时才更新秩.
*/
#include<iostream>
#include<cstdio>
#define MAXN 20001
using namespace std;
int n,m,tot,root[MAXN],s[MAXN];
struct data{int lc,rc,deep,x;}tree[MAXN*20];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void build(int &k,int l,int r)
{
k=++tot;
if(l==r){tree[k].x=l;return ;}
int mid=(l+r)>>1;
build(tree[k].lc,l,mid);
build(tree[k].rc,mid+1,r);
return ;
}
int query(int k,int l,int r,int x)
{
if(l==r) return k;
int mid=(l+r)>>1;
if(x<=mid) return query(tree[k].lc,l,mid,x);
else return query(tree[k].rc,mid+1,r,x);
}
int find(int root,int x)
{
int p=query(root,1,n,x);
if(x==tree[p].x) return p;
else return find(root,tree[p].x);
}
void change(int &k,int last,int l,int r,int x,int y)
{
k=++tot;tree[k].lc=tree[last].lc,tree[k].rc=tree[last].rc;
if(l==r) {
tree[k].x=y;tree[k].deep=tree[last].deep;
return ;
}
int mid=(l+r)>>1;
if(x<=mid) change(tree[k].lc,tree[last].lc,l,mid,x,y);
else change(tree[k].rc,tree[last].rc,mid+1,r,x,y);
return ;
}
void updata(int k,int l,int r,int x)
{
if(l==r){tree[k].deep++;return ;}
int mid=(l+r)>>1;
if(x<=mid) updata(tree[k].lc,l,mid,x);
else updata(tree[k].rc,mid+1,r,x);
return ;
}
void union_s(int l1,int l2,int i)
{
if(tree[l1].deep>tree[l2].deep) swap(l1,l2);
change(root[i],root[i-1],1,n,tree[l1].x,tree[l2].x);
if(tree[l1].deep==tree[l2].deep) updata(root[i],1,n,tree[l2].x);
return ;
}
int main()
{
int x,y,z,l1,l2;
n=read(),m=read();
build(root[0],1,n);
for(int i=1;i<=m;i++)
{
z=read();
if(z==1)
{
x=read(),y=read();
root[i]=root[i-1];
l1=find(root[i],x),l2=find(root[i],y);
if(tree[l1].x!=tree[l2].x) union_s(l1,l2,i);
}
else if(z==2) x=read(),root[i]=root[x];
else {
x=read(),y=read();
root[i]=root[i-1];
l1=find(root[i],x),l2=find(root[i],y);
if(l1==l2) printf("1\n");
else printf("0\n");
}
}
return 0;
}
Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)的更多相关文章
- BZOJ 3674 可持久化并查集加强版(主席树变形)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [Submit][Sta ...
- BZOJ 3673 可持久化并查集 by zky && BZOJ 3674 可持久化并查集加强版 可持久化线段树
既然有了可持久化数组,就有可持久化并查集.. 由于上课讲过说是只能按秩合并(但是我也不确定...),所以就先写了按秩合并,相当于是维护fa[]和rk[] getf就是在这棵树中找,直到找到一个点的fa ...
- bzoj 3673 可持久化并查集 by zky
Description n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的状态(查询算作操作)3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n ...
- 3673: 可持久化并查集 by zky
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 2170 Solved: 978[Submit][Status ...
- 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- 2019.01.21 bzoj3674: 可持久化并查集加强版(主席树+并查集)
传送门 题意:维护可持久化并查集,支持在某个版本连边,回到某个版本,在某个版本 询问连通性. 思路: 我们用主席树维护并查集fafafa数组,由于要查询历史版本,因此不能够用路径压缩. 可以考虑另外一 ...
- BZOJ 3673: 可持久化并查集(可持久化并查集+启发式合并)
http://www.lydsy.com/JudgeOnline/problem.php?id=3673 题意: 思路: 可持久化数组可以用可持久化线段树来实现,并查集的查询操作和原来的一般并查集操作 ...
- bzoj 3673 可持久化并查集
本质上是维护两个可持久化数组,用可持久化线段树维护. /************************************************************** Problem: ...
- 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树
没什么好说的. 可持久化线段树,叶子节点存放父亲信息,注意可以规定编号小的为父亲. Q:不是很清楚空间开多大,每次询问父亲操作后修改的节点个数是不确定的.. #include<bits/stdc ...
随机推荐
- 运输计划[二分答案 LCA 树上差分]
也许更好的阅读体验 \(\mathcal{Description}\) 原题链接 概括一下题意 给一颗有\(n\)个点带边权的树,有\(m\)个询问,每次询问\(u,v\)两点间的权值和,你可以将树中 ...
- ES与关系型数据库的通俗比较
1.在Elasticsearch中,文档归属于一种类型(type),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统关系型数据库: Relational DB -> D ...
- easyExcel用于导入导出
1.添加依赖: <!-- 现在已经更新到1.1.2-beta5 --> <dependency> <groupId>com.alibaba</groupId& ...
- RuntimeError: Model class users.models.UserProfile doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
Django启动的时候报错 File "/home/hehecat/PycharmProjects/MxShop/MxShop/urls.py", line 23, in from ...
- 【转载】 C#使用Select方法快速获取List集合集合中某个属性的所有值集合
在C#的List集合操作或者数组操作中,有时候我们需要获取到List集合元素中所有的对象的某个属性,然后存放到一个数组集合中,此时就可以使用到List集合以及数组的扩展方法Select方法快速实现获取 ...
- FreeRTOS 中断配置和临界段
中断屏蔽寄存器 PRIMASK.FAULTMASK和BASEPRI 1.PRIMASK:这是个只有1个位的寄存器.当它置1时, 就关掉所有可屏蔽的异常,只剩下 NMI和硬fault可以响应.它的缺省值 ...
- 基本代码、插值表达式、v-cloak
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【leetcode】338 .Counting Bits
原题 Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate t ...
- 记录java+testng运行selenium(二)---定义元素类及浏览器
一: 元素类 整体思路: 1. 根据状态可分可见和不可见两种 2. 同一个路径可以查找单个元素或多个元素 3. 获取元素text或者指定的value值 4. selenium对元素操作有两种,一是通过 ...
- 如何11 周打造全能Python工程师!
在这个大数据和人工智能的时代,不管你是编程初学者,还是想学习一门其他语言充实自己,Python都是最好的选择之一. 它简洁.优雅.易学,被越来越多的大学作为计算机新生的入门语言: 它是大数据和人工智能 ...