「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」【模板】可持久化并查集的更多相关文章

  1. 「LuoguP4147」 玉蟾宫(并查集

    题目背景 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. 题目描述 这片土地被分成N*M个格子,每个格子里写着'R'或者'F ...

  2. 「ZJOI2007」「LuoguP1169」棋盘制作(并查集

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8×88 \times 88×8大小的黑白相间的方阵,对应八八六十四卦 ...

  3. 洛谷P3402 【模板】可持久化并查集 [主席树,并查集]

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

  4. 【洛谷 P3402】 【模板】可持久化并查集

    题目链接 可持久化并查集,就是用可持久化线段树维护每个版本每个节点的父亲,这样显然是不能路径压缩的,否则我们需要恢复太多状态. 但是这并不影响我们启发式合并,于是,每次把深度小的连通块向深度大的上并就 ...

  5. bzoj3674 可持久化并查集

    我是萌萌的任意门 可持久化并查集的模板题-- 做法好像很多,可以标号法,可以森林法. 本来有O(mloglogn)的神算法(按秩合并+倍增),然而我这种鶸渣就只会写O(mlog2n)的民科算法--再加 ...

  6. [bzoj] 3673 3674 可持久化并查集 || 可持久化数组

    原题 加强版 题意: 可持久化并查集模板-- 题解: 用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态. 不能用路径压缩,但是要按置合并,使复杂度保证在O(log) #include&l ...

  7. Luogu 3402 可持久化并查集

    点开这题纯属无聊……不过既然写掉了,那就丢一个模板好了 不得不说,可持久化并查集实现真的很暴力,就是把并查集的数组弄一个主席树可持久化. 有一点要注意的是不能写路径压缩,这样跳版本的时候会错,所以弄一 ...

  8. bzoj3673 & bzoj3674 & 洛谷P3402 可持久化并查集

    题目:bzoj3673:https://www.lydsy.com/JudgeOnline/problem.php?id=3673 bzoj3674:https://www.lydsy.com/Jud ...

  9. 算法笔记--可撤销并查集 && 可持久化并查集

    可撤销并查集模板: struct UFS { stack<pair<int*, int>> stk; int fa[N], rnk[N]; inline void init(i ...

随机推荐

  1. google插件跨域含用户请求WebApi解决的方案

    问题描述: google插件跨域请求WebApi相关解决方案 1.ajax解决含登录用户信息 $.ajax({ url: url, type: "POST", timeout: 6 ...

  2. 一起学Netty(一)之HelloWorld,可以聊天的小程序哦

    转自于:http://blog.csdn.net/linuu/article/details/51306480

  3. Hello 2020D(多重集)

    如果有一对时间对在某一场馆有时间重合而这一对时间对在另一场馆没有时间重合,则输出NO,否则输出YES. #define HAVE_STRUCT_TIMESPEC #include<bits/st ...

  4. Go_type

    1. type的定义和使用 Go语言支持函数式编程,可以使用高阶编程语法.一个函数可以作为另一个函数的参数,也可以作为另一个函数的返回值,那么在定义这个高阶函数的时候,如果函数的类型比较复杂,我们可以 ...

  5. C#中的注释

    帮助程序员便于阅读代码 单行注释 // 多行注释 /* * */ 文档注释 /// <summary> /// ... /// <summary>

  6. AngularJS请求数据提示resource from url not allowed by $sceDelegate policy

    AngularJS iframe跨域打开内容时报错 解决方案 使用  $sceDelegateProvider  配置跨域请求域名 config.js app.config(function($sce ...

  7. Android学习使用基本界面组件(下拉框,单选框,复选框,数字转轮,滚动条)

    (一)建立单选框按钮 RadioGroup和RadioButton建立单选框按钮 字符串资源文件: <resources> <string name="app_name&q ...

  8. 【WPF学习】第十四章 事件路由

    由上一章可知,WPF中的许多控件都是内容控件,而内容控件可包含任何类型以及大量的嵌套内容.例如,可构建包含图形的按钮,创建混合了文本和图片内容的标签,或者为了实现滚动或折叠的显示效果而在特定容器中放置 ...

  9. SpringBoot 开发的那些小趣事儿

    经过这次在公司实习中获取到的经历,我发现确实有时候书本上的知识发挥的作用微乎其微,好像是被问题打了太极拳一样,你明明想去攻克这个地方,他却给你报了其他地方的错误. 平常的一些小项目根本就不能匹配到企业 ...

  10. 改变input[type=range]的样式 动态滑动

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...