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 ...
随机推荐
- react 提示消息队列 (支持动态添加,删除,多实例化)
import React from 'react' import PropTypes from 'prop-types' import AnimationOperateFeedbackInfo fro ...
- Spring Cloud Alibaba学习笔记(2) - Nacos服务发现
1.什么是Nacos Nacos的官网对这一问题进行了详细的介绍,通俗的来说: Nacos是一个服务发现组件,同时也是一个配置服务器,它解决了两个问题: 1.服务A如何发现服务B 2.管理微服务的配置 ...
- Spring全框架讲解
Day 01: https://blog.csdn.net/sinat_29211659/article/details/81335229
- SQL链接服务器查询-OPENQUERY的使用
OpenQuery: 用途:与其他Server交互的技术,通过它能够直接访问其他数据库资源.可以跨平台连接,包括Oracle --创建链接服务器 exec sp_addlinkedserver ' ...
- .Dot NET Cored简介
一.诞生原因 1..Net平台封闭. 2.不支持跨平台. 3.受限于Windows平台性能,无法解决高性能场景. 二.优势 1.支持跨平台.开源.系统建设成本低. 2.效率和性能较好. 三.缺点 1. ...
- 十年感悟之 python之路
本文由 简悦 SimpRead 转码, 原文地址 https://laisky.com/p/python-road/ Changelog: updated at 2019/9/6 一.概述 本文起源于 ...
- JacksonJson的使用
JacksonJson是SpringMVC内置的json处理工具,其中有一个ObjectMapper类,可以方便的实现对json的处理: //对象转字符串 // json处理工具 private Ob ...
- coco creator编辑动画坑之拖图片
如图所示,批量选中多张图片之后,拖到右下角的框中,发现有时候可以有时候不行.这个我觉得是个软件的bug 后来经过测试发现只有在粉红色圈的高度才可以正确放入图片,否则都放不了.
- 在SAP除了使用Cordova生产移动应用外,还有这种方式
本文和Jerry过去的文章不太一样,算不上Jerry的知识分享,只是记录一下Jerry用React-Native把应用安装到Android手机上遇到的一些问题,方便以后查看. Jerry的同事Leo用 ...
- python中json序列化时汉字变成编码的解决方式
我们在使用json模块时,如果被序列化对象中不包含汉字,当然没有任何问题,但是有汉字会被编译成unicode码: import json dic = {","sex":& ...