P3402

通过主席树维护不同版本的并查集,注意要采用按秩合并的方式,路径压缩可能会爆。

 1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N = 3e5 + 10;
4 int n, m, rt[N * 30];
5 struct node {
6 int ls, rs, dep, fa;//fa的值都是在1~n范围中的
7 }t[N * 30];
8 namespace SegmentTree {
9 #define mid ((l + r) >> 1)
10 #define lson t[i].ls, l, mid
11 #define rson t[i].rs, mid + 1, r
12 int cnt;
13 void build(int &i, int l, int r) {
14 i = ++ cnt;
15 if (l == r) {t[i].fa = l; return ;}//初始时节点父亲就是自己
16 build(lson), build(rson);
17 }
18 void merge(int j, int &i, int l, int r, int pos1, int pos2) {
19 //pos1是深度较小的节点的fa,找到pos1的位置,将该位置的fa改为pos2,也就是合并操作
20 i = ++ cnt;
21 t[i] = t[j];//复制
22 if (l == r) {
23 t[i].fa = pos2;
24 return ;
25 }
26 if (pos1 <= mid) merge(t[j].ls, lson, pos1, pos2);
27 else merge(t[j].rs, rson, pos1, pos2);
28 }
29 void update(int i, int l, int r, int pos) {
30 if (l == r) {t[i].dep ++; return ;}
31 if (pos <= mid) update(lson, pos);
32 else update(rson, pos);
33 }
34 int query(int i, int l, int r, int pos) {//返回节点pos的编号
35 if (l == r) return i;
36 if (pos <= mid) return query(lson, pos);
37 else return query(rson, pos);
38 }
39 int find(int i, int pos) {//类似并查集找祖先操作
40 int now = query(i, 1, n, pos);
41 if (t[now].fa == pos) return now;//也是返回节点编号
42 return find(i, t[now].fa);
43 }
44 #undef mid
45 #undef lson
46 #undef rson
47 }
48 using namespace SegmentTree;
49 int main() {
50 scanf("%d %d", &n, &m);
51 build(rt[0], 1, n);
52 for (int i = 1; i <= m; i ++) {
53 int opt, x, y;
54 scanf("%d %d", &opt, &x);
55 if(opt == 1) {//合并x, y所在集合
56 scanf("%d", &y);
57 int posx, posy;
58 rt[i] = rt[i - 1];//复制新版本
59 posx = find(rt[i], x), posy = find(rt[i], y);
60 if (t[posx].fa != t[posy].fa) {//按秩合并
61 if (t[posx].dep > t[posy].dep) swap(posx, posy);
62 merge(rt[i - 1], rt[i], 1, n, t[posx].fa, t[posy].fa);
63 if (t[posx].dep == t[posy].dep) update(rt[i], 1, n, t[posy].fa);
64 //避免深度相同
65 }
66 }
67 else if(opt == 2) rt[i] = rt[x];
68 else if(opt == 3) {
69 scanf("%d", &y);
70 rt[i] = rt[i - 1];
71 int posx, posy;
72 posx = find(rt[i], x), posy = find(rt[i], y);
73 if (t[posx].fa == t[posy].fa) puts("1");
74 else puts("0");
75 }
76 }
77 return 0;
78 }

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

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

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

  2. 洛谷P3402 可持久化并查集

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. bzoj3674 可持久化并查集

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

随机推荐

  1. 第八天pyhton3 函数的返回值、作用域

    返回值 pthon函数使用return语句返回"返回值": 所有函数都有返回值,如果没有return语句,隐式调用return None: return 语句并不一定是函数的语句块 ...

  2. 最新豆瓣top250爬虫案例代码分析[注释齐全]

    导入包 # json包 import json #正则表达式包 import re import requests from requests import RequestException 定义爬取 ...

  3. Redis进阶篇:发布订阅模式原理与运用

    "65 哥,如果你交了个漂亮小姐姐做女朋友,你会通过什么方式将这个消息广而告之给你的微信好友?" "那不得拍点女朋友的美照 + 亲密照弄一个九宫格图文消息在朋友圈发布大肆 ...

  4. spring使用junit单元测试

    <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test& ...

  5. Github文件在线加速下载

    众所周知,GitHub是一个巨大的开源宝库,以及程序员和编程爱好者的聚集地,诸多优秀的开源项目全部都是位于GitHub上.但是每当我们看到优秀的开源项目,准备去下(bai)载(piao)时,会发现速度 ...

  6. 持久化-Powershell配置文件持久性

    持久化-Powershell配置文件持久性 概述 可以使用Powershell配置文件进行持久性和/或特权升级. 执行 获取可以滥用的powershell配置文件,这取决于你拥有的权限. $PROFI ...

  7. 第九十二篇:Vue 自定义指令

    好家伙, 1.什么是自定义指令? vue官方提供了v-text,v-for,v-model,v-if等常用的指令.除此之外vue还允许开发者自定义指令. 2.自定义指令的分类 vue中的自定义指令分为 ...

  8. ubuntu 16.04 搭建docker

    1.为确保运行的不是旧版Docker sudo apt-get remove docker docker-engine docker.io 2.添加Docker COmmunity Edition 所 ...

  9. spark 读取Geomesa(Hbase)数据

    package com.grady.geomesa import org.apache.hadoop.conf.Configuration import org.apache.spark.SparkC ...

  10. Thrift RPC改进—更加准确的超时管理

    前言: 之前我们组内部使用Thrift搭建了一个小型的RPC框架,具体的实现细节可以参考我之前的一篇技术文章:https://www.cnblogs.com/kaiblog/p/9507642.htm ...