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 ...
随机推荐
- 从ftp获取文件并生成压缩包
依赖 <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</a ...
- react实现提示消息容器,可以动态添加,删除内部子提示消息
import React, { useState, useRef, useEffect } from 'react' import PropTypes from 'prop-types' import ...
- AtCoder Grand Contest 034
A:如果C在D左侧,显然先让B到达终点再让A走即可,否则先判断一下A是否可以在某处超过B.也就是先判断一下起点与终点之间是否有连续的障碍,若有则无解:然后若C在D左侧输出Yes,否则判断B和D之间是否 ...
- MacBook Pro 安装composer及Yii2.0
最近想看看Yii的一些东西,需要安装一下composer curl -sS https://getcomposer.org/installer | php 此操作会下载最新版本到当前的目录下 然后将下 ...
- VS.NET(C#)--2.1认识控件
Web控件 四种控件 1.HTML控件 2.HTML服务器控件 在服务器端执行 3.ASP.NET服务器控件 在服务器端执行 4.用户控件和自定义控件 用户自定义控件在服务器端执行 注意: ...
- MongoDB的删除操作
1.MongoDB 删除数据库的语法格式如下: db.dropDatabase() > show dbs admin .000GB config .000GB local .000GB sda ...
- Apache老版本下载地址
有时候我们想做测试或者使用旧版本软件时,往往发现官方网站已经下架,以Apache为例: Apache旧版本下载地址:http://archive.apache.org/dist/httpd/ .... ...
- python selectors模块实现 IO多路复用机制的上传下载
import selectorsimport socketimport os,time BASE_DIR = os.path.dirname(os.path.abspath(__file__))''' ...
- MySQL常见interview
mysql支持的存储引擎,以及各自区别 常用的有myisam,innodb,bdb myisam是mysql默认存储引擎:不支持事务和外键,访问速度快,对事物完整性没有要求或者以select.inse ...
- spark 实现多文件输出
需求 不同的key输出到不同的文件 txt文件 multiple.txt 中国;22 美国;4342 中国;123 日本;44 日本;6 美国;55 美国;43765 日本;786 日本;55 sca ...