可持久化并(xian)查(duan)集(shu)
随便地点开了这道可持久化并查集,发现了真相...这和并查集有 PI 关系哦.除了find_father(而且还不能路径压缩),全都是线段树0.0
题目链接: luogu.org
题目没什么描述,就是三个操作:
1. 合并 a b
2. 回到第 k 步操作(三个操作均算操作)
3. 查询 a b 在当前版本的并查集中是否在同一棵树中
那么...
对于操作 1 :我们在线段树中修改节点 fa 的父亲为 fb
对于操作 2 :简单,我们直接把当前版本的根指向第 k 版本的根,一行就解决了(引起可持久化的罪魁祸首解决倒是简单)
对于操作 3 :查询 fa 和 fb 输出就好了(貌似就操作 1 有点不好理解)
对于操作 1 ,模拟如图:
代码如下:
//by Judge
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ls ch[now][0]
#define rs ch[now][1]
#define mid (l+r>>1)
#define swap(a,b) (a)^=(b)^=(a)^=(b)
using namespace std;
const int M=2e5+;
inline int read(){
int x=,f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
int n,m,cnt;
int ed[M<<],f[M<<],ch[M<<][],dep[M<<];
inline void build(int& now,int l,int r){ //建树,叶子节点认 左(右)端点 为父亲
now=++cnt; if(l==r){ f[now]=l; return ; }
build(ls,l,mid), build(rs,mid+,r);
}
void update(int& now,int las,int l,int r,int pos,int fa){ //修改 pos 的父亲为 fa
now=++cnt; if(l==r){ f[now]=fa,dep[now]=dep[las]; return ; }
if(pos<=mid) update(ls,ch[las][],l,mid,pos,fa);
else update(rs,ch[las][],mid+,r,pos,fa);
}
int query(int now,int l,int r,int pos){ //询问在 now 版本中 pos 的节点编号
if(l==r) return now;
if(pos<=mid) return query(ls,l,mid,pos);
else return query(rs,mid+,r,pos);
}
void add(int now,int l,int r,int pos){ //增加 now 版本中 pos 所在叶子节点的深度
if(l==r) { ++dep[now]; return ; }
if(pos<=mid) add(ls,l,mid,pos);
else add(rs,mid+,r,pos);
}
int find(int ed,int x){ //查询祖先
int fa=query(ed,,n,x);
if(x==f[fa]) return fa;
return find(ed,f[fa]);
}
int main(){
n=read(),m=read(),build(ed[],,n);
for(int i=,opt,a,b,f1,f2;i<=m;++i)
switch(opt=read()){
case : //不显然
ed[i]=ed[i-],a=read(),b=read();
f1=find(ed[i],a),f2=find(ed[i],b);
if(f[f1]==f[f2]) break;
if(dep[f1]>dep[f2]) swap(f1,f2);
update(ed[i],ed[i-],,n,f[f1],f[f2]);
if(dep[f1]==dep[f2]) add(ed[i],,n,f[f2]); break; //这里 emmm,看上文
case : //显然
ed[i]=ed[read()]; break;
case : //显然
ed[i]=ed[i-],a=read(),b=read();
f1=find(ed[i],a), f2=find(ed[i],b);
puts(f[f1]==f[f2]?"":""); break;
}
return ;
}
上面代码可能出锅,下面代码应该没毛病...
//by Judge
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ls ch[now][0]
#define rs ch[now][1]
#define mid (l+r>>1)
#define swap(a,b) (a)^=(b)^=(a)^=(b)
using namespace std;
const int M=2e5+;
inline int read(){
int x=,f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
int n,m,cnt;
int ed[M<<],f[M<<],ch[M<<][],dep[M<<];
inline void build(int& now,int l,int r){
now=++cnt; if(l==r){ f[now]=l; return ; }
build(ls,l,mid), build(rs,mid+,r);
}
void update(int& now,int las,int l,int r,int pos,int fa){
now=++cnt; if(l==r){ f[now]=fa,dep[now]=dep[las]; return ; }
ls=ch[las][], rs=ch[las][];
if(pos<=mid) update(ls,ch[las][],l,mid,pos,fa);
else update(rs,ch[las][],mid+,r,pos,fa);
}
int query(int now,int l,int r,int pos){
if(l==r) return now;
if(pos<=mid) return query(ls,l,mid,pos);
else return query(rs,mid+,r,pos);
}
void add(int now,int l,int r,int pos){
if(l==r) { ++dep[now]; return ; }
if(pos<=mid) add(ls,l,mid,pos);
else add(rs,mid+,r,pos);
}
int find(int ed,int x){
int fa=query(ed,,n,x);
if(x==f[fa]) return fa;
return find(ed,f[fa]);
}
int main(){
n=read(),m=read(),build(ed[],,n);
for(int i=,opt,a,b,f1,f2;i<=m;++i)
switch(opt=read()){
case :
ed[i]=ed[i-],a=read(),b=read();
f1=find(ed[i],a),f2=find(ed[i],b);
if(f[f1]==f[f2]) break;
if(dep[f1]>dep[f2]) swap(f1,f2);
update(ed[i],ed[i-],,n,f[f1],f[f2]);
if(dep[f1]==dep[f2]) add(ed[i],,n,f[f2]); break;
case : ed[i]=ed[read()]; break;
case :
ed[i]=ed[i-],a=read(),b=read();
f1=find(ed[i],a), f2=find(ed[i],b);
puts(f[f1]==f[f2]?"":""); break;
}
return ;
}
by Judge
可持久化并(xian)查(duan)集(shu)的更多相关文章
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- redis 消息队列(发布订阅)、持久化(RDB、AOF)、集群(cluster)
一:订阅: 192.168.10.205:6379> SUBSCRIBE test Reading messages... (press Ctrl-C to quit) 1) "sub ...
- luogu T96516 [DBOI2019]持盾 可持久化线段树+查分
因为题中的操作是区间加法,所以满足前缀相减性. 而每一次查询的时候还是单点查询,所以直接用可持久化线段树维护差分数组,然后查一个前缀和就行了. code: #include <bits/stdc ...
- Zookeeper节点增删改查与集群搭建(笔记)
1.上传文件目录说明 上传的文件一般放在 /home/下 安装文件一般在 /usr/local/下 2. 安装zookeeper 2.1将zookeeper-3.4.11.tar.gz拷贝到/home ...
- [BZOJ3673&3674]可持久化并查集&加强版
题目大意:让你实现一个可持久化的并查集(3674强制在线). 解题思路:刚刚介绍了一个叫rope的神器:我是刘邦,在这两题(实际上两题没什么区别)就派上用场了. 正解应该是主席树||可持久化平衡树,然 ...
- [luoguP1197] [JSOI2008]星球大战(并查集)
传送门 思维!重要的是思维! 题目让删边,然而并查集不好删边(并!查!集!啊) 我们离线处理,从后往前添边,这样并查集就可以用了. 用并查集维护连通块个数即可. ——代码 #include <c ...
- 谈一谈并查集QAQ(上)
最近几日理了理学过的很多oi知识...发现不知不觉就有很多的知识忘记了... 在聊聊并查集的时候顺便当作巩固吧.... 什么是并查集呢? ( Union Find Set ) 是一种用于处理分离集合的 ...
- ActiveMQ集群应用
ActiveMQ集群 ActiveMQ具有强大和灵活的集群功能,但在使用的过程中会发现很多的缺点,ActiveMQ的集群方式主要由两种:Master-Slave和Broker Cluster. 1.M ...
- MongoDB分片集群原理、搭建及测试详解
随着技术的发展,目前数据库系统对于海量数据的存储和高效访问海量数据要求越来越高,MongoDB分片机制就是为了解决海量数据的存储和高效海量数据访问而生. MongoDB分片集群由mongos路由进程( ...
随机推荐
- TestNG安装及使用
安装:https://www.cnblogs.com/xusweeter/p/6559196.html使用:https://www.cnblogs.com/liwu/p/5113936.html 作用 ...
- mm-wiki安装部署
参考连接:https://github.com/skyhack1212/mm-wiki 打开 https://github.com/phachon/mm-wiki/releases 找到对应平台的版本 ...
- Golang 入门系列(五)GO语言中的面向对象
前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/ ...
- Mysql完整约束性
一.介绍 约束条件与数据类型的宽度一样,都是可选参数 作用:用于保证数据的完整性和一致性主要分为: PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录 FOREIGN KEY ...
- java基础-不用ide如何打包
java基础-不用ide如何打包 1. 建立目录 src存放源文件 classes存放编译文件 2. 建立类文件 主类 package test.ant; import test.ant.MyTool ...
- EntityFramework优化:第一次启动优化
1. 预先生成视图 通过代码的方式来预先生成视图,要求EntityFramework是6.0及以上版本. 控制台程序: using System.Data.Entity.Infrastructure; ...
- java基础3之IO
流 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接.类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流. 流的种类 字符 ...
- JS异常
当 JavaScript 引擎执行 JavaScript 代码时,会发生各种错误. 可能是语法错误,通常是程序员造成的编码错误或错别字. 可能是拼写错误或语言中缺少的功能(可能由于浏览器差异). 可能 ...
- Oracle 查看链接数、创建索引等的DDL语句
select count(*),machine from v$session group by machine 今天打算将一个数据库的索引在另一个测试库上重新创建一遍,研究了一下. set pages ...
- Docker:dockerfile自动构建镜像 [六]
一.手动docker镜像的缺点 相对于手动制作的docker镜像,使用dockerfile构建的镜像有以下优点: 1.dockerfile只有几kb,便于传输 2.使用dockerfile构建出来的镜 ...