随便地点开了这道可持久化并查集,发现了真相...这和并查集有 PI 关系哦.除了find_father(而且还不能路径压缩),全都是线段树0.0

题目链接: luogu.org

题目没什么描述,就是三个操作:

1. 合并 a b

2. 回到第 k 步操作(三个操作均算操作)

3. 查询 a b 在当前版本的并查集中是否在同一棵树中

那么...

对于操作 1 :我们在线段树中修改节点 fa 的父亲为 fb


对于操作 2 :简单,我们直接把当前版本的根指向第 k 版本的根,一行就解决了(引起可持久化的罪魁祸首解决倒是简单)

对于操作 3 :查询 fafb 输出就好了(貌似就操作 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)的更多相关文章

  1. [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

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

  2. redis 消息队列(发布订阅)、持久化(RDB、AOF)、集群(cluster)

    一:订阅: 192.168.10.205:6379> SUBSCRIBE test Reading messages... (press Ctrl-C to quit) 1) "sub ...

  3. luogu T96516 [DBOI2019]持盾 可持久化线段树+查分

    因为题中的操作是区间加法,所以满足前缀相减性. 而每一次查询的时候还是单点查询,所以直接用可持久化线段树维护差分数组,然后查一个前缀和就行了. code: #include <bits/stdc ...

  4. Zookeeper节点增删改查与集群搭建(笔记)

    1.上传文件目录说明 上传的文件一般放在 /home/下 安装文件一般在 /usr/local/下 2. 安装zookeeper 2.1将zookeeper-3.4.11.tar.gz拷贝到/home ...

  5. [BZOJ3673&3674]可持久化并查集&加强版

    题目大意:让你实现一个可持久化的并查集(3674强制在线). 解题思路:刚刚介绍了一个叫rope的神器:我是刘邦,在这两题(实际上两题没什么区别)就派上用场了. 正解应该是主席树||可持久化平衡树,然 ...

  6. [luoguP1197] [JSOI2008]星球大战(并查集)

    传送门 思维!重要的是思维! 题目让删边,然而并查集不好删边(并!查!集!啊) 我们离线处理,从后往前添边,这样并查集就可以用了. 用并查集维护连通块个数即可. ——代码 #include <c ...

  7. 谈一谈并查集QAQ(上)

    最近几日理了理学过的很多oi知识...发现不知不觉就有很多的知识忘记了... 在聊聊并查集的时候顺便当作巩固吧.... 什么是并查集呢? ( Union Find Set ) 是一种用于处理分离集合的 ...

  8. ActiveMQ集群应用

    ActiveMQ集群 ActiveMQ具有强大和灵活的集群功能,但在使用的过程中会发现很多的缺点,ActiveMQ的集群方式主要由两种:Master-Slave和Broker Cluster. 1.M ...

  9. MongoDB分片集群原理、搭建及测试详解

    随着技术的发展,目前数据库系统对于海量数据的存储和高效访问海量数据要求越来越高,MongoDB分片机制就是为了解决海量数据的存储和高效海量数据访问而生. MongoDB分片集群由mongos路由进程( ...

随机推荐

  1. go笔记-值传递、引用传递

    eg: func sliceModify(slice []int) { // slice[0] = 88 slice = append(slice, ) } func main() { slice : ...

  2. python部署lvs

    lvs-dr-rr import paramiko vip = '192.168.254.250' ds = '192.168.254.17' rs1 = '192.168.254.37' rs2 = ...

  3. First ServiceStack Service

    博客1:ServiceStack Web Service 创建与调用简单示列 博客2:Hbuilder+vs2017 web api开发app 官方文档:servicestack docs 1.手动下 ...

  4. (PAT)L2-012 关于堆的判断 (最小堆)

    题目链接:https://www.patest.cn/contests/gplt/L2-012 将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: “ ...

  5. webpack4

    本地安装: npm init -y cnpm install webpack webpack-cli webpack-dev-server --save-dev 然后装一些所需要的loader和插件: ...

  6. php_network_getaddresses: getaddrinfo failed 原因

    一般在调用外部服务请求时候,有时由于配置问题无法访问,phph会报一个php_network_getaddresses: getaddrinfo failed: Name or servicenot ...

  7. 前端cookie操作用到的一些小总结

    前后端完全分离的是目前web开发的大趋势,包括现下流行的前端框架的应用vue,angular,在不同页面跳转时,前端需要对用户登录状态进行判断,拿到用户的id,除了Ajax从服务器端获取数据外,对co ...

  8. golang 数组、切片、map

    一.数组(类似python的list) 数组的长度一旦定义了就不能动态增长.并且存储的数据类型必须相同. 创建方法: var 数组名 [长度]数据类型 例如: package main import ...

  9. Eclipse常用设置及快捷键

    1. Eclipse常用设置 1.1 代码自动提示 选择菜单:Window -> Preferences -> Java -> Editor -> Content Assist ...

  10. C# 数组、HashSet等内存耗尽的解决办法

    在C#中,如果数据量太大,就会出现 'System.OutOfMemoryException' 异常. 解决办法来自于Stack Overflow和MSDN    https://docs.micro ...