@(BZOJ)[可持久化并査集]

Description

n个集合 m个操作

操作:

1 a b 合并a,b所在集合

2 k 回到第k次操作之后的状态(查询算作操作)

3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

请注意本题采用强制在线,所给的a,b,k均经过加密,加密方法为x = x xor lastans,lastans的初始值为0

0<n,m<=2*10^5

Sample Input

5 6
1 1 2
3 1 2
2 1
3 0 3
2 1
3 1 2

Sample Output

1
0
1

Solution

模板题.

BZOJ上的数据傻到不行.

还是去xsy上提交吧

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm> const int N = 1 << 18, M = 1 << 18;
int n; namespace Zeonfai
{
inline int getInt()
{
int a = 0, sgn = 1;
char c; while(! isdigit(c = getchar()))
sgn *= c == '-' ? -1 : 1; while(isdigit(c))
a = a * 10 + c - '0', c = getchar(); return a * sgn;
}
} struct persistentDisjointSet
{
int rt[M], tp; struct data
{
int pre, dep;
}; struct node
{
int suc[2];
data infr;
}nd[N * 18 + M * 18]; inline int newNode(int pre, int dep)
{
nd[tp].suc[0] = nd[tp].suc[1] = -1;
nd[tp].infr.pre = pre, nd[tp].infr.dep = dep;
return tp ++;
} int build(int L, int R)
{
int u = newNode(L == R ? L : -1, 1); if(L == R)
return u; int mid = L + R >> 1;
nd[u].suc[0] = build(L, mid), nd[u].suc[1] = build(mid + 1, R);
return u;
} inline void initialize()
{
memset(rt, -1, sizeof(rt));
tp = 0;
rt[0] = build(1, n);
} int find(int L, int R, int u, int a)
{
if(L == R)
return u; int mid = L + R >> 1; if(a <= mid)
return find(L, mid, nd[u].suc[0], a);
else
return find(mid + 1, R, nd[u].suc[1], a);
} inline int access(int tm, int a)
{
while(int u = find(1, n, rt[tm], a))
{
if(nd[u].infr.pre == a)
return a; a = nd[u].infr.pre;
}
} int newSegmentTree(int _u, int L, int R, int a, int b)
{
int u = tp ++;
nd[u] = nd[_u]; if(L == R)
return u; int mid = L + R >> 1; if((a >= L && a <= mid) || (b >= L && b <= mid))
nd[u].suc[0] = newSegmentTree(nd[_u].suc[0], L, mid, a, b); if((a > mid && a <= R) || (b > mid && b <= R))
nd[u].suc[1] = newSegmentTree(nd[_u].suc[1], mid + 1, R, a, b); return u;
} inline void merge(int tm, int a, int b)
{
int rtA = access(tm - 1, a), rtB = access(tm - 1, b); if(rtA == rtB)
{
rt[tm] = rt[tm - 1];
return;
} rt[tm] = newSegmentTree(rt[tm - 1], 1, n, rtA, rtB);
int u = find(1, n, rt[tm], rtA), v = find(1, n, rt[tm], rtB); if(nd[u].infr.dep == nd[v].infr.dep)
{
++ nd[u].infr.dep;
nd[v].infr.pre = rtA;
return;
} if(nd[u].infr.dep > nd[v].infr.dep)
nd[v].infr.pre = rtA;
else
nd[u].infr.pre = rtB;
} inline void accessHistory(int tm, int _tm)
{
rt[tm] = rt[_tm];
} inline int query(int tm, int a, int b)
{
rt[tm] = rt[tm - 1];
int preA = access(tm, a), preB = access(tm, b); if(preA == preB)
return 1;
else
return 0;
}
}st; int main()
{
#ifndef ONLINE_JUDGE
freopen("BZOJ3674.in", "r", stdin);
freopen("BZOJ3674.out", "w", stdout);
#endif using namespace Zeonfai; n = getInt();
int m = getInt(), lstAns = 0, tm = 0;
st.initialize(); while(m --)
{
int opt = getInt(); if(opt == 1)
{
int a = getInt() ^ lstAns, b = getInt() ^lstAns;
st.merge(++ tm, a, b);
}
else if(opt == 2)
{
int a = getInt() ^ lstAns;
st.accessHistory(++ tm, a);
}
else if(opt == 3)
{
int a = getInt() ^ lstAns, b = getInt() ^ lstAns;
printf("%d\n", lstAns = st.query(++ tm, a, b));
}
}
}

BZOJ3674 可持久化并査集的更多相关文章

  1. bzoj3673可持久化并查集 by zky&&bzoj3674可持久化并查集加强版

    bzoj3673可持久化并查集 by zky 题意: 维护可以恢复到第k次操作后的并查集. 题解: 用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以 ...

  2. bzoj3674 可持久化并查集

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

  3. BZOJ3674: 可持久化并查集加强版

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3674 题解:主要是可持久化的思想.膜拜了一下hzwer的代码后懂了. 其实本质是可持久化fa数 ...

  4. 2019.01.21 bzoj3674: 可持久化并查集加强版(主席树+并查集)

    传送门 题意:维护可持久化并查集,支持在某个版本连边,回到某个版本,在某个版本 询问连通性. 思路: 我们用主席树维护并查集fafafa数组,由于要查询历史版本,因此不能够用路径压缩. 可以考虑另外一 ...

  5. bzoj3673 bzoj3674可持久化并查集

    并查集都写不来了qwq 之前写的是错的 sz的初值都是0,这样怎么加就都是0了,水这道题还是可以,但是加强版就过不了了 #include<cstdio> #include<cstri ...

  6. BZOJ3674 可持久化并查集加强版 可持久化 并查集

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3674 题意概括 n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的 ...

  7. [BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky

    思路: 用主席树维护并查集森林,每次连接时新增结点. 似乎并不需要启发式合并,我随随便便写了一个就跑到了3674第一页?3673是这题的弱化版,本来写个暴力就能过,现在借用加强版的代码(去掉异或),直 ...

  8. 【可持久化数组】【rope】bzoj3673 bzoj3674 可持久化并查集 by zky

    rope教程:http://blog.csdn.net/iamzky/article/details/38348653 Code(bzoj3673): #include<cstdio> # ...

  9. BZOJ3674可持久化并查集(模板)

    没什么可说的,就是一个可持久化线段树维护一个数组fa以及deep按秩合并好了 注意一下强制在线 蒟蒻的我搞了好长时间QAQ 贴代码: #include<cstdio> #include&l ...

随机推荐

  1. 如何优化sql查询

    借鉴https://www.cnblogs.com/ssrstm/p/5753068.html和https://www.cnblogs.com/exe19/p/5786806.html 1. 对查询进 ...

  2. systemverilog(3)之Randomize

    what to randomize? (1) primary input data <==one data (2)encapsulated input data <== muti grou ...

  3. laravel服务容器(IOC控制反转,DI依赖注入),服务提供者,门脸模式

    laravel的核心思想: 服务容器: 容器:就是装东西的,laravel就是一个个的对象 放入:叫绑定 拿出:解析 使用容器的目的:这里面讲到的是IOC控制反转,主要是靠第三方来处理具体依赖关系的解 ...

  4. Google实践中总结的Python规范,get了吗?

    好的代码风格,给人舒服的感觉,今天介绍一下谷歌的Python风格规范 1 分号 不要在行尾加分号, 也不要用分号将两条命令放在同一行. 2 行长度 每行不超过80个字符:不要使用反斜杠连接行.Pyth ...

  5. checkStyle使用手册

    1. Annotations(注解:5个) Annotation Use Style(注解使用风格) 这项检查可以控制要使用的注解的样式. Missing Deprecated(缺少deprecad) ...

  6. wlan

    一.概述 CSMA/CD    --->以太网介质 CSMA/CA------->无线介质 IEEE----->802.11   a  b  g  e  f   h  i  j 分类 ...

  7. HDU 4417 Super Mario(划分树问题求不大于k的数有多少)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. 2017 Wuhan University Programming Contest (Online Round) D. Events,线段树区间更新+最值查询!

    D. Events 线段树区间更新查询区间历史最小值,看似很简单的题意写了两天才写出来. 题意:n个数,Q次操作,每次操作对一个区间[l,r]的数同时加上C,然后输出这段区间的历史最小值. 思路:在线 ...

  9. nginx中access_log和nginx.conf中的log_format用法

    nginx服务器日志相关指令主要有两条: 一条是log_format,用来设置日志格式; 另外一条是access_log,用来指定日志文件的存放路径.格式和缓存大小 可以参加ngx_http_log_ ...

  10. 【bzoj4519】[Cqoi2016]不同的最小割 分治+最小割

    题目描述 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割.对于带权图来说,将所有顶点处在不同 ...