点开这题纯属无聊……不过既然写掉了,那就丢一个模板好了

不得不说,可持久化并查集实现真的很暴力,就是把并查集的数组弄一个主席树可持久化。

有一点要注意的是不能写路径压缩,这样跳版本的时候会错,所以弄一个按秩合并来降低时间复杂度。

总时间复杂度$O(nlog^2n)$。

听说用siz实现按秩合并会比较好,因为这样还能查询集合大小,有时间以后补上。

Code:

#include <cstdio>
using namespace std; const int N = 1e5 + ;
const int M = 2e5 + ; int n, qn; inline void read(int &X) {
X = ;
char ch = ;
int op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} struct Node {
int lc, rc, dep, fa;
}; namespace PUfs {
Node s[N * ];
int root[M * ], nodeCnt; #define mid ((l + r) >> 1) void build(int &p, int l, int r) {
p = ++nodeCnt;
if(l == r) {
s[p].fa = l;
return;
} build(s[p].lc, l, mid);
build(s[p].rc, mid + , r);
} void modify(int &p, int l, int r, int x, int f, int pre) {
p = ++nodeCnt;
if(l == r) {
s[p].fa = f;
s[p].dep = s[pre].dep;
return;
} s[p].lc = s[pre].lc, s[p].rc = s[pre].rc;
if(x <= mid) modify(s[p].lc, l, mid, x, f, s[pre].lc);
else modify(s[p].rc, mid + , r, x, f, s[pre].rc);
} void add(int p, int l, int r, int x) {
if(l == r) {
s[p].dep++;
return;
}
if(x <= mid) add(s[p].lc, l, mid, x);
else add(s[p].rc, mid + , r, x);
} int query(int p, int l, int r, int x) {
if(l == r) return p; if(x <= mid) return query(s[p].lc, l, mid, x);
else return query(s[p].rc, mid + , r, x);
} int find(int now, int x) {
int f = query(now, , n, x);
if(s[f].fa == x) return f;
return find(now, s[f].fa);
} } using namespace PUfs; inline void print(int p) {
printf("%d: ", p);
for(int j = ; j <= n; j++)
printf("%d ", s[find(root[p], j)].fa);
/* for(int j = 1; j <= n; j++)
printf("%d ", query(root[p], 1, n, j)); */
printf("\n");
} inline void swap(int &x, int &y) {
int t = x;
x = y;
y = t;
} int main() {
read(n), read(qn); nodeCnt = ;
build(root[], , n); // print(0); for(int op, i = ; i <= qn; i++) {
read(op);
if(op == ) {
root[i] = root[i - ];
int x, y;
read(x), read(y);
int fx = find(root[i], x), fy = find(root[i], y);
if(s[fx].fa == s[fy].fa) continue;
if(s[fx].dep > s[fy].dep) swap(fx, fy);
modify(root[i], , n, s[fx].fa, s[fy].fa, root[i - ]);
if(s[fx].dep == s[fy].dep) add(root[i], , n, s[fy].fa);
}
if(op == ) {
int k;
read(k);
root[i] = root[k];
}
if(op == ) {
root[i] = root[i - ];
int x, y;
read(x), read(y);
int fx = find(root[i], x), fy = find(root[i], y);
if(s[fx].fa == s[fy].fa) puts("");
else puts("");
}
// print(i);
} return ;
}

Luogu 3402 可持久化并查集的更多相关文章

  1. 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]

    题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...

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

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

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

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

  4. 带撤销并查集 & 可持久化并查集

    带撤销并查集支持从某个元素从原来的集合中撤出来,然后加入到一个另外一个集合中,或者删除该元素 用一个映射来表示元素和并查集中序号的关系,代码中用\(to[x]\) 表示x号元素在并查集中的 id 删除 ...

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

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

  6. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  7. bzoj3674 可持久化并查集

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

  8. 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树

    没什么好说的. 可持久化线段树,叶子节点存放父亲信息,注意可以规定编号小的为父亲. Q:不是很清楚空间开多大,每次询问父亲操作后修改的节点个数是不确定的.. #include<bits/stdc ...

  9. 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id ...

随机推荐

  1. mysql 在Windows下自动备份

    1.一般备份方法主要为两种: 直接保存数据库data文件夹 mysqldump 用sql命令备份(文件存放目录必须存在) 首先cmd进入MySQL\bin,然后mysqldump --default- ...

  2. 19年博客flag

    目录 为什么没有年终总结 为什么今天更新了 19年博客flag 个人博客链接:我在马路边 https://hhongwen.cn 更好的阅读体验点击查看原文:19年博客flag 原创博客,转载请注明出 ...

  3. Java代码使用正则验证和常用工具方法

    1.正则验证邮箱 public static boolean checkEmail(String email){ boolean flag = false; try{ String check = & ...

  4. WPF案例:如何设计搜索框(自定义控件的原则和方法)

    我们平时自定义WPF控件的方法有:Style,DataTemplate,ControlTemplate, DependencyProperty, CustomControl等几个方法. 按照优先顺序应 ...

  5. 如何批量清除128组节点db上面的过期的binlog,释放磁盘空间。(转)

    如果10台以内的db的话,自己手动ssh进去,clean就足以,但是上百台呢,就要写脚本了.大概思路:在 一台db跳转机上面, 写一个脚本,访问slave,远程获取正在复制的master上面的binl ...

  6. 检测一个DLL文件是x64还是x86

    对于一个DLL,我们如何判定其是32位的还是64位的,或者是any cpu的platform? Visual Studio提供了一个很好的工具:corflags,这个是内嵌到Developer Com ...

  7. Makefile 自动产生依赖 ***

    代码如下: 其实这里主要是为每个C文件建立一个同名的后缀为.d.该文件的作用是使用gcc的-M属性来自动生成.o文件的头文件依赖关系. 第1,2,4都好理解. 第2行解释: 使用gcc -M 的属性将 ...

  8. 解决IDEA输入法不跟随

    1.关掉idea后在idea的安装路径下把jre64文件夹删掉,或者重命名也行,如把jre64改成jre642: 2.升级jdk版本至jdk 8u45以上 3.把Java安装路径下的jre文件拷贝到I ...

  9. java代码包装类----------Integer

    总结:我的笔试挂了..基础的继承不懂不会.我不知道到底是哪里的问题. 要好好反思 package com.da.ima2; public class jrfk { // int整型不能直接转化为Int ...

  10. Linux打包下载命令

    语法:tar [主选项+辅选项] 文件或者目录使用该命令时,主选项是必须要有的,它告诉tar要做什么事情,辅选项是辅助使用的,可以选用. 主选项: c 创建新的档案文件.如果用户想备份一个目录或是一些 ...