「luogu3402」【模板】可持久化并查集
「luogu3402」【模板】可持久化并查集
传送门
我们可以用一个可持久化数组来存每个节点的父亲。
单点信息更新和查询就用主席树多花 一个 \(\log\) 的代价来搞。
然后考虑如何合并两个点。
由于我们要做到可持久化,所以我们就考虑用启发式合并。
至于路径压缩,ta好像会因为某些原因而MLE和TLE 其实我也没试过
那么我们在合并的时候就只需要借助主席树完成单点查询和修改就好了。
注意一个地方值得注意,就是在修改时因为我们的线段树是可持久化的,所以会通向之前版本的节点,所以不要覆盖之前的信息,不然就不是可持久化了。
参考代码:
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
template < class T > inline void swap(T& a, T& b) { T t = a; a = b; b = t; }
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 2e5 + 5;
int n, m, tot, rt[_];
struct node { int fa, siz; } ;
struct chairmantree { int lc, rc; node u; } t[_ << 5];
inline void build(int& p, int l = 1, int r = n) {
p = ++tot;
if (l == r) { t[p].u = (node) { l, 1 }; return ; }
int mid = (l + r) >> 1;
build(t[p].lc, l, mid), build(t[p].rc, mid + 1, r);
}
inline void update(int& p, int q, int x, int fa, int siz, int l = 1, int r = n) {
t[p = ++tot] = t[q];
if (l == r) { t[p].u = (node) { fa ? fa : t[p].u.fa, siz ? siz : t[p].u.siz }; return ; }
int mid = (l + r) >> 1;
if (x <= mid) update(t[p].lc, t[q].lc, x, fa, siz, l, mid);
else update(t[p].rc, t[q].rc, x, fa, siz, mid + 1, r);
}
inline node query(int p, int x, int l = 1, int r = n) {
if (l == r) return t[p].u;
int mid = (l + r) >> 1;
if (x <= mid) return query(t[p].lc, x, l, mid);
else return query(t[p].rc, x, mid + 1, r);
}
inline node Find(int p, int x) {
node Fa = query(rt[p], x);
if (Fa.fa == x) return Fa; else return Find(p, Fa.fa);
}
inline void merge(int p, int x, int y) {
node fx = Find(p, x), fy = Find(p, y);
if (fx.siz < fy.siz) swap(fx, fy);
update(rt[p], rt[p], fx.fa, 0, fx.siz + fy.siz);
update(rt[p], rt[p], fy.fa, fx.fa, 0);
}
int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n), read(m), build(rt[0]);
for (rg int opt, x, y, i = 1; i <= m; ++i) {
read(opt);
if (opt == 1) read(x), read(y), rt[i] = rt[i - 1], merge(i, x, y);
if (opt == 2) read(x), rt[i] = rt[x];
if (opt == 3) read(x), read(y), rt[i] = rt[i - 1], puts(Find(i, x).fa == Find(i, y).fa ? "1" : "0");
}
return 0;
}
「luogu3402」【模板】可持久化并查集的更多相关文章
- 「LuoguP4147」 玉蟾宫(并查集
题目背景 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. 题目描述 这片土地被分成N*M个格子,每个格子里写着'R'或者'F ...
- 「ZJOI2007」「LuoguP1169」棋盘制作(并查集
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8×88 \times 88×8大小的黑白相间的方阵,对应八八六十四卦 ...
- 洛谷P3402 【模板】可持久化并查集 [主席树,并查集]
题目传送门 可持久化并查集 n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 ...
- 【洛谷 P3402】 【模板】可持久化并查集
题目链接 可持久化并查集,就是用可持久化线段树维护每个版本每个节点的父亲,这样显然是不能路径压缩的,否则我们需要恢复太多状态. 但是这并不影响我们启发式合并,于是,每次把深度小的连通块向深度大的上并就 ...
- bzoj3674 可持久化并查集
我是萌萌的任意门 可持久化并查集的模板题-- 做法好像很多,可以标号法,可以森林法. 本来有O(mloglogn)的神算法(按秩合并+倍增),然而我这种鶸渣就只会写O(mlog2n)的民科算法--再加 ...
- [bzoj] 3673 3674 可持久化并查集 || 可持久化数组
原题 加强版 题意: 可持久化并查集模板-- 题解: 用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态. 不能用路径压缩,但是要按置合并,使复杂度保证在O(log) #include&l ...
- Luogu 3402 可持久化并查集
点开这题纯属无聊……不过既然写掉了,那就丢一个模板好了 不得不说,可持久化并查集实现真的很暴力,就是把并查集的数组弄一个主席树可持久化. 有一点要注意的是不能写路径压缩,这样跳版本的时候会错,所以弄一 ...
- bzoj3673 & bzoj3674 & 洛谷P3402 可持久化并查集
题目:bzoj3673:https://www.lydsy.com/JudgeOnline/problem.php?id=3673 bzoj3674:https://www.lydsy.com/Jud ...
- 算法笔记--可撤销并查集 && 可持久化并查集
可撤销并查集模板: struct UFS { stack<pair<int*, int>> stk; int fa[N], rnk[N]; inline void init(i ...
随机推荐
- fiddler中文乱码解决方案
只用添加一个注册表变量就行 cmd窗口执行regedit命令,在弹出的注册表编辑界面找到fiddler 右击新建一个字符传值 HeaderEncodingGBK 结果如上图右所示~ 重启fiddler ...
- java项目上有个红色感叹号(在project Explorer视图下)
启动项目时一直报错,检查也没问题,最后看到项目上有个红色感叹号,发现是jar包路径不对,把错误路径的jar包移除,然后再重新添加即可.
- Python学习(七)——匿名函数、map函数、filter函数、reduce函数与其他内置函数
匿名函数 lambda x: x + 1 # lambda:定义匿名函数的关键字 # x:形参 # x+1:程序处理逻辑 fun = lambda x: x + 1 print(fun(5)) #6 ...
- Flutter 中的表单
一.Flutter 常用表单介绍 Flutter 中常见的表单有 TextField 单行文本框,TextField 多行文本框.CheckBox.Radio.Switch CheckboxLi ...
- Git - Windows 下, gitbash 打开资源管理器
1. 概述 windows 下 gitbash 打开 资源管理器 2. 场景 资源管理唤起 gitbash 步骤 进入目录 鼠标右击 在 弹出菜单 中, 找到 Git Bash Here 结果 打开一 ...
- ALSA driver--PCM实例创建框架
在介绍PCM 之前,我们先给出创建PCM实例的框架. #include <sound/pcm.h> .... /* hardware definition */ static struct ...
- 学会C#可以做什么
C#基于.NET Framework 和 .NET CORE平台 Client/Server 客户端/服务端 windows桌面应用程序 winform 2D WPF 3D Browser/Se ...
- P&R 4
Floorplan 要做好fp需要掌握哪些知识和技能? 通常遇到fp问题大致的debug步骤和方法有哪些? 如何衡量fp的QA? 通常FP是做PR 最关键也最具技术含量的一个环节.相对于后续的PR步骤 ...
- C++:打开一个文件夹下一系列的文件
可以用MFC的CFileFind类: FILE *pFile=NULL; CFileFind cff; CString fstr="C:\\page\\*.*"//所以用文件和文件 ...
- TensorFlow使用RNN实现手写数字识别
学习,笔记,有时间会加注释以及函数之间的逻辑关系. # https://www.cnblogs.com/felixwang2/p/9190664.html # https://www.cnblogs. ...