BZOJ3674 可持久化并査集
@(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 可持久化并査集的更多相关文章
- bzoj3673可持久化并查集 by zky&&bzoj3674可持久化并查集加强版
bzoj3673可持久化并查集 by zky 题意: 维护可以恢复到第k次操作后的并查集. 题解: 用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以 ...
- bzoj3674 可持久化并查集
我是萌萌的任意门 可持久化并查集的模板题-- 做法好像很多,可以标号法,可以森林法. 本来有O(mloglogn)的神算法(按秩合并+倍增),然而我这种鶸渣就只会写O(mlog2n)的民科算法--再加 ...
- BZOJ3674: 可持久化并查集加强版
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3674 题解:主要是可持久化的思想.膜拜了一下hzwer的代码后懂了. 其实本质是可持久化fa数 ...
- 2019.01.21 bzoj3674: 可持久化并查集加强版(主席树+并查集)
传送门 题意:维护可持久化并查集,支持在某个版本连边,回到某个版本,在某个版本 询问连通性. 思路: 我们用主席树维护并查集fafafa数组,由于要查询历史版本,因此不能够用路径压缩. 可以考虑另外一 ...
- bzoj3673 bzoj3674可持久化并查集
并查集都写不来了qwq 之前写的是错的 sz的初值都是0,这样怎么加就都是0了,水这道题还是可以,但是加强版就过不了了 #include<cstdio> #include<cstri ...
- BZOJ3674 可持久化并查集加强版 可持久化 并查集
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3674 题意概括 n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的 ...
- [BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky
思路: 用主席树维护并查集森林,每次连接时新增结点. 似乎并不需要启发式合并,我随随便便写了一个就跑到了3674第一页?3673是这题的弱化版,本来写个暴力就能过,现在借用加强版的代码(去掉异或),直 ...
- 【可持久化数组】【rope】bzoj3673 bzoj3674 可持久化并查集 by zky
rope教程:http://blog.csdn.net/iamzky/article/details/38348653 Code(bzoj3673): #include<cstdio> # ...
- BZOJ3674可持久化并查集(模板)
没什么可说的,就是一个可持久化线段树维护一个数组fa以及deep按秩合并好了 注意一下强制在线 蒟蒻的我搞了好长时间QAQ 贴代码: #include<cstdio> #include&l ...
随机推荐
- 如何优化sql查询
借鉴https://www.cnblogs.com/ssrstm/p/5753068.html和https://www.cnblogs.com/exe19/p/5786806.html 1. 对查询进 ...
- systemverilog(3)之Randomize
what to randomize? (1) primary input data <==one data (2)encapsulated input data <== muti grou ...
- laravel服务容器(IOC控制反转,DI依赖注入),服务提供者,门脸模式
laravel的核心思想: 服务容器: 容器:就是装东西的,laravel就是一个个的对象 放入:叫绑定 拿出:解析 使用容器的目的:这里面讲到的是IOC控制反转,主要是靠第三方来处理具体依赖关系的解 ...
- Google实践中总结的Python规范,get了吗?
好的代码风格,给人舒服的感觉,今天介绍一下谷歌的Python风格规范 1 分号 不要在行尾加分号, 也不要用分号将两条命令放在同一行. 2 行长度 每行不超过80个字符:不要使用反斜杠连接行.Pyth ...
- checkStyle使用手册
1. Annotations(注解:5个) Annotation Use Style(注解使用风格) 这项检查可以控制要使用的注解的样式. Missing Deprecated(缺少deprecad) ...
- wlan
一.概述 CSMA/CD --->以太网介质 CSMA/CA------->无线介质 IEEE----->802.11 a b g e f h i j 分类 ...
- HDU 4417 Super Mario(划分树问题求不大于k的数有多少)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 2017 Wuhan University Programming Contest (Online Round) D. Events,线段树区间更新+最值查询!
D. Events 线段树区间更新查询区间历史最小值,看似很简单的题意写了两天才写出来. 题意:n个数,Q次操作,每次操作对一个区间[l,r]的数同时加上C,然后输出这段区间的历史最小值. 思路:在线 ...
- nginx中access_log和nginx.conf中的log_format用法
nginx服务器日志相关指令主要有两条: 一条是log_format,用来设置日志格式; 另外一条是access_log,用来指定日志文件的存放路径.格式和缓存大小 可以参加ngx_http_log_ ...
- 【bzoj4519】[Cqoi2016]不同的最小割 分治+最小割
题目描述 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割.对于带权图来说,将所有顶点处在不同 ...