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(主席树+启发式合并)的更多相关文章

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

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

  2. BZOJ 3673 可持久化并查集 by zky && BZOJ 3674 可持久化并查集加强版 可持久化线段树

    既然有了可持久化数组,就有可持久化并查集.. 由于上课讲过说是只能按秩合并(但是我也不确定...),所以就先写了按秩合并,相当于是维护fa[]和rk[] getf就是在这棵树中找,直到找到一个点的fa ...

  3. bzoj 3673 可持久化并查集 by zky

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

  4. 3673: 可持久化并查集 by zky

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 2170  Solved: 978[Submit][Status ...

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

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

  6. 2019.01.21 bzoj3674: 可持久化并查集加强版(主席树+并查集)

    传送门 题意:维护可持久化并查集,支持在某个版本连边,回到某个版本,在某个版本 询问连通性. 思路: 我们用主席树维护并查集fafafa数组,由于要查询历史版本,因此不能够用路径压缩. 可以考虑另外一 ...

  7. BZOJ 3673: 可持久化并查集(可持久化并查集+启发式合并)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3673 题意: 思路: 可持久化数组可以用可持久化线段树来实现,并查集的查询操作和原来的一般并查集操作 ...

  8. bzoj 3673 可持久化并查集

    本质上是维护两个可持久化数组,用可持久化线段树维护. /************************************************************** Problem: ...

  9. 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树

    没什么好说的. 可持久化线段树,叶子节点存放父亲信息,注意可以规定编号小的为父亲. Q:不是很清楚空间开多大,每次询问父亲操作后修改的节点个数是不确定的.. #include<bits/stdc ...

随机推荐

  1. 运输计划[二分答案 LCA 树上差分]

    也许更好的阅读体验 \(\mathcal{Description}\) 原题链接 概括一下题意 给一颗有\(n\)个点带边权的树,有\(m\)个询问,每次询问\(u,v\)两点间的权值和,你可以将树中 ...

  2. ES与关系型数据库的通俗比较

    1.在Elasticsearch中,文档归属于一种类型(type),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统关系型数据库: Relational DB -> D ...

  3. easyExcel用于导入导出

    1.添加依赖: <!-- 现在已经更新到1.1.2-beta5 --> <dependency> <groupId>com.alibaba</groupId& ...

  4. 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 ...

  5. 【转载】 C#使用Select方法快速获取List集合集合中某个属性的所有值集合

    在C#的List集合操作或者数组操作中,有时候我们需要获取到List集合元素中所有的对象的某个属性,然后存放到一个数组集合中,此时就可以使用到List集合以及数组的扩展方法Select方法快速实现获取 ...

  6. FreeRTOS 中断配置和临界段

    中断屏蔽寄存器 PRIMASK.FAULTMASK和BASEPRI 1.PRIMASK:这是个只有1个位的寄存器.当它置1时, 就关掉所有可屏蔽的异常,只剩下 NMI和硬fault可以响应.它的缺省值 ...

  7. 基本代码、插值表达式、v-cloak

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 【leetcode】338 .Counting Bits

    原题 Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate t ...

  9. 记录java+testng运行selenium(二)---定义元素类及浏览器

    一: 元素类 整体思路: 1. 根据状态可分可见和不可见两种 2. 同一个路径可以查找单个元素或多个元素 3. 获取元素text或者指定的value值 4. selenium对元素操作有两种,一是通过 ...

  10. 如何11 周打造全能Python工程师!

    在这个大数据和人工智能的时代,不管你是编程初学者,还是想学习一门其他语言充实自己,Python都是最好的选择之一. 它简洁.优雅.易学,被越来越多的大学作为计算机新生的入门语言: 它是大数据和人工智能 ...