【BZOJ】3674: 可持久化并查集加强版
题解
感觉全世界都写过只有我没写过
毕竟是板子还是挺简单的,只要用可持久化线段树维护一下数组的形态就好了,每个数组里面维护这个数组的father,和这个点所在树的最长链的深度(如果这个点是根按秩合并要用)
为了避免返回两个值可以直接返回所在线段树节点的编号
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <bitset>
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define pb push_back
#define mo 974711
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define MAXN 200005
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 - '0' + c;
c = getchar();
}
res = res * f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int N,M;
struct node {
int f,dep,lc,rc;
}tr[MAXN * 80];
int rt[MAXN],Ncnt;
void build(int &u,int l,int r) {
u = ++Ncnt;
if(l == r) {
tr[u].f = l;
tr[u].dep = 1;
return;
}
int mid = (l + r) >> 1;
build(tr[u].lc,l,mid);
build(tr[u].rc,mid + 1,r);
}
int Query(int u,int L,int R,int pos) {
if(L == R) return u;
int mid = (L + R) >> 1;
if(pos <= mid) return Query(tr[u].lc,L,mid,pos);
else return Query(tr[u].rc,mid + 1,R,pos);
}
void Change(int x,int &y,int L,int R,int pos,int v) {
y = ++Ncnt;
tr[y] = tr[x];
if(L == R) {tr[y].f = v;return;}
int mid = (L + R) >> 1;
if(pos <= mid) Change(tr[x].lc,tr[y].lc,L,mid,pos,v);
else Change(tr[x].rc,tr[y].rc,mid + 1,R,pos,v);
}
void Inc_dep(int x,int &y,int L,int R,int pos) {
y = ++Ncnt;
tr[y] = tr[x];
if(L == R) {tr[y].dep++;return;}
int mid = (L + R) >> 1;
if(pos <= mid) Inc_dep(tr[x].lc,tr[y].lc,L,mid,pos);
else Inc_dep(tr[x].rc,tr[y].rc,mid + 1,R,pos);
}
int getfa(int u,int x) {
int p = Query(u,1,N,x);
if(tr[p].f == x) return p;
else return getfa(u,tr[p].f);
}
void Solve() {
read(N);read(M);
build(rt[0],1,N);
int op,a,b;
for(int i = 1 ; i <= M ; ++i) {
read(op);
if(op == 1) {
rt[i] = rt[i - 1];
read(a);read(b);
a = getfa(rt[i],a);b = getfa(rt[i],b);
if(a == b) continue;
if(tr[a].dep < tr[b].dep) Change(rt[i],rt[i],1,N,tr[a].f,tr[b].f);
else if(tr[b].dep < tr[a].dep) Change(rt[i],rt[i],1,N,tr[b].f,tr[a].f);
else {
Change(rt[i],rt[i],1,N,tr[a].f,tr[b].f);
Inc_dep(rt[i],rt[i],1,N,tr[b].f);
}
}
else if(op == 2) {
read(a);
rt[i] = rt[a];
}
else if(op == 3) {
rt[i] = rt[i - 1];
read(a);read(b);
a = getfa(rt[i],a);b = getfa(rt[i],b);
if(a == b) {puts("1");}
else puts("0");
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
【BZOJ】3674: 可持久化并查集加强版的更多相关文章
- BZOJ 3674 可持久化并查集加强版(路径压缩版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
- BZOJ 3674 可持久化并查集加强版(按秩合并版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
- BZOJ 3674 可持久化并查集加强版(主席树变形)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [Submit][Sta ...
- bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)
Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...
- BZOJ 3673 可持久化并查集 by zky && BZOJ 3674 可持久化并查集加强版 可持久化线段树
既然有了可持久化数组,就有可持久化并查集.. 由于上课讲过说是只能按秩合并(但是我也不确定...),所以就先写了按秩合并,相当于是维护fa[]和rk[] getf就是在这棵树中找,直到找到一个点的fa ...
- bzoj 3674 可持久化并查集加强版——可持久化并查集
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3674 用主席树维护 fa[ ] 和 siz[ ] .改 fa[ ] 和改 siz[ ] 都 ...
- BZOJ 3674: 可持久化并查集加强版
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3674 题意:三种操作:(1)合并ab所在集合:(2)查询ab是否在一个集合:(3) ...
- BZOJ 3674 可持久化并查集加强版 可持久化并查集
题目大意:同3673 强制在线 同3673 仅仅只是慢了一些0.0 这道题仅仅写路径压缩比仅仅写启示式合并要快一点点 两个都写就慢的要死0.0 改代码RE的可能是内存不够 #include<cs ...
- 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- bzoj 3673&3674 可持久化并查集&加强版(可持久化线段树+启发式合并)
CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...
随机推荐
- python---函数补充(变量传递),语句执行顺序(入栈顺序)
一:函数补充 默认作为函数参数的数据,是浅拷贝传递.不是和C等语言一样,产生一个临时变量. class T: def __init__(self,num): print(id(num)) self.n ...
- 算法: 排序: 归并排序(Merge)
http://www.codeproject.com/Articles/805587/Merge-Sort
- 20155301 2016-2017-2 《Java程序设计》第5周学习总结
20155301 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 1.1try.catch关键词,在用户不小心输入错误的时候,程序会出现错误信息,将代表错误的 ...
- JS设计模式——7.工厂模式(示例-XHR)
XHR工厂 基本实现 var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXHR']); var SimpleHandl ...
- 【FCS NOI2018】福建省冬摸鱼笔记 day4
第四天. 动态规划专题,讲师:闫神 讲了一些DP优化技巧,然而思想难度好大啊……根本没想到能优化那地步,连DP方程都没有呢. 不过有几题我还是想明白了. 讲了单调队列,决策单调性,四边形不等式,斜率优 ...
- 【工具记录】Linux口令破解
1.基础知识 /etc/passwd:记录着用户的基本属性,所有用户可读 字段含义如下: 用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell eg: root:x:0:0:root ...
- js中字符串的常用方法
一.普通方法 1.字符方法 动态方法:1.str.charAt(index); 返回子字符串,index为字符串下标,index取值范围[0,str.length-1] 动态方法:2.str.cha ...
- centos7 部署 seafile
=============================================== 2018/5/13_第1次修改 ccb_warlock == ...
- Session和Cookie,Django的自动登录机制
什么是Cookie? Cookie是浏览器的本地存储机制,存储服务器返回的各种信息,下次发起请求时再发送给服务端,比如访问baidu 什么是Session? 刚才说道,Cookie存储服务端返回的信息 ...
- Vue.js 基础快速入门
Vue.js是一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.Vue.js提供了简洁.易于理解的API,使得我们能够快速地上手并使用Vue.js 如果之前已经习惯了用jQue ...