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 ...
随机推荐
- 计算机应用第七次作业 html制作个人音乐播放站点
计算机应用第七次作业 html制作个人音乐播放站点 请访问下边网址查看具体操作: http://www.cnblogs.com/qingyundian/p/7878892.html
- sublime点击预览未起作用?教你如何设置支持浏览器预览
我用的text3版,其他版本未试,但应该也有效. 安了个view in browser插件,然而点击预览未起作用. 搜解决方法,发现了另一个插件,sidebar enhancements,设置快捷键预 ...
- Codeforces Round #510 #A
http://codeforces.com/contest/1042/problem/A 题目大意就是: 现在公园里有n个长椅(要多长有多长),第i个长椅上有a[i]个人(泰山崩于前而不乱),现在又有 ...
- python数据类型、字符编码、文件处理-练习
练习-字符串 # 写代码,有如下变量,请按照要求实现每个功能 (共6分,每小题各0.5分) name = " aleX" # ) 移除 name 变量对应的值两边的空格,并输出处理 ...
- angular 列表渲染机制
watchCollection:监听集合元素的变化,而不能监听到集合元素内部的属性变化,只要集合中元素的引用没有发生变化,则认为无变化.用这个api也可以监听普通对象的第一层属性变化. watch:监 ...
- html块级元素和行级元素的区别和使用
行内.块状元素区别: 1.行内元素与块级函数可以相互转换,通过修改display属性值来切换块级元素和行内元素,行内元素display:inline,块级元素display:block. 2.行内元素 ...
- chardet使用方法
简单用法 chardet的使用非常简单,主模块里面只有一个函数detect.detect有一个参数,要求是bytes类型.bytes类型可以通过读取网页内容.open函数的rb模式.带b前缀的字符串. ...
- SQLServer数据库查看死锁、堵塞情况
在压力测试过程中,不间断的按F5键执行上面的SQL语句,如果出现死锁或者堵塞现象,就会在执行结果中罗列出来.如果每次连续执行SQL,都有死锁或者堵塞出现,说明死锁或者堵塞的比较严重. --每秒死锁数量 ...
- Python3中super()的参数传递
1. super([type[, object-or-type]]) super() 在使用时至少传递一个参数,且这个参数必须是一个类. 通过super()获取到的是一个代理对象,通过这个对象去查找父 ...
- 织梦dedecms自定义表单设置必填项
1. 用php验证 在plus/diy.php的第 40行下加 //增加必填字段判断 if($required!=''){ if(preg_match('/,/', $required)) { $re ...