随便地点开了这道可持久化并查集,发现了真相...这和并查集有 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. 【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  2. windows service承载的web api宿主搭建(Microsoft.Owin+service)

    今天突然想起改良一下以前搭建的“windows service承载的web api”服务,以前也是直接引用的类库,没有使用nuget包,时隔几年应该很旧版本了吧.所以本次把需要nuget获取的包记录一 ...

  3. 三十、小程序解析HTML(对富文本返回数据的处理)

    1.首先需要下载插件wxParse 下载地址 https://github.com/ZCLegendary/WXNews 百度云盘有保存 WXML <import src="../.. ...

  4. JS 设计模式三 -- 策略模式

    策略模式 概念 定义一系列算法,把它们一个个封装起来. 将算法的使用与算法的实现分离开来 实现 // 加权映射关系 var levelMap = { S: 10, A: 8, B: 6, C: 4 } ...

  5. js中 ajax动态新增节点无法触发点击事件

    在写ajax加载数据的时候发现,后面添加进来的demo节点元素,失去了之前的点击事件. 其实最简单的方法就是直接在标签中写onclick="",但是这样写有些场景的是实现不了的,最 ...

  6. 部署alinode监控线上应用

    参考: https://segmentfault.com/a/1190000013089124

  7. @RequestParam、@RequestBody和@ModelAttribute区别

    一.@RequestParamGET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上1. @RequestParam(org.springframework.web.b ...

  8. VScode中python环境配置

    vscode中python环境配置 想要在vscode中运行python代码必须要告诉vscode使用哪个解释器才行 方法1. 打开命令面板(Ctrl+Shift+P)输入Python: Select ...

  9. Excel将一列数据变为两列

    如下表可将第一列分散到第二列和第三列 A B C 1 =OFFSET($A$1,(ROW(A1)-1)*2+COLUMN(A1)-1,) &"" =OFFSET($A$2, ...

  10. 内网ntp时间同步配置

    选择局域网中的一台机器作为ntp服务器,在ntp server上安装并启动ntpd客户端上要关闭ntpd,安装ntpdateCentOS7上这两个软件都是自带的,只需根据需要打开或者关闭.注意客户端机 ...