【BZOJ3674】可持久化并查集加强版
可持久化并查集我觉得就是可持久化数组的一种应用。可持久化数组,顾名思义,就是有历史版本的数组,那么如果我们暴力修改储存的话,修改O(n)查询O(1),空间O(n*m),这样肯定不可行,那么我们发现主席树有这样的功能,他可以快速复制,修改O(log),查询O(log),空间(m*log),是一个可行的方案。然后我们可持久化f数组维护fa,每次按照深度启发式合并,不进行路径压缩,这样能保证时间复杂度位单次O(log^2),空间复杂度为O(2*n+m*log)。我不知道为什么不路径压缩,路径压缩是完全可以的,但是他的时间复杂度和空间复杂度似乎都不如不路径压缩看,而且似乎并不好打。
#include <cstdio>
using namespace std;
inline void read(int &sum){
register char ch=getchar();
for(sum=;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';sum=(sum<<)+(sum<<)+ch-'',ch=getchar());
}
const int N=;
struct Segment_Tree{
Segment_Tree *ch[];int f,deep;
void* operator new(size_t);
}*root[N],*null,*C,*mempool;
int n,m;
void* Segment_Tree :: operator new(size_t){
if(C==mempool)C=new Segment_Tree[(<<)+],mempool=C+(<<)+;
return C++;
}
inline void build(Segment_Tree *&p,int l,int r){
p=new Segment_Tree,p->deep=p->f=;
if(l==r){
p->f=l,p->deep=,p->ch[]=p->ch[]=null;
return;
}
build(p->ch[],l,(l+r)>>);
build(p->ch[],((l+r)>>)+,r);
}
inline void insert(Segment_Tree *&p,Segment_Tree *last,int pos,int key,int l,int r){
p=new Segment_Tree,*p=*last;
if(l==r){
p->f=key;return;
}
if(pos<=((l+r)>>))insert(p->ch[],last->ch[],pos,key,l,((l+r)>>));
else insert(p->ch[],last->ch[],pos,key,((l+r)>>)+,r);
}
inline void update(Segment_Tree *p,int pos){
register int l=,r=n;
while(l!=r){
if(pos<=((l+r)>>)){
p=p->ch[],r=((l+r)>>);
}else{
p=p->ch[],l=((l+r)>>)+;
}
}
p->deep++;
}
inline int deep(Segment_Tree *p,int pos){
register int l=,r=n;
while(l!=r){
if(pos<=((l+r)>>)){
p=p->ch[],r=((l+r)>>);
}else{
p=p->ch[],l=((l+r)>>)+;
}
}
return p->deep;
}
inline int F(Segment_Tree *p,int pos){
register int l=,r=n;
while(l!=r){
if(pos<=((l+r)>>)){
p=p->ch[],r=((l+r)>>);
}else{
p=p->ch[],l=((l+r)>>)+;
}
}
return p->f;
}
inline int find_root(Segment_Tree *p,int x){
int fa=F(p,x);
return fa==x?x:find_root(p,fa);
}
inline void Init(){
null=new Segment_Tree,null->ch[]=null->ch[]=null,null->f=,null->deep=;
read(n),read(m);
build(root[],,n);
}
inline void Work(){
register int ans=,opt,a,b,x,y,d1,d2;
for(register int i=;i<=m;i++){
read(opt);
switch(opt){
case :read(a),a^=ans,read(b),b^=ans;
x=find_root(root[i-],a),y=find_root(root[i-],b);
if(x==y){
root[i]=root[i-];
break;
}
d1=deep(root[i-],x),d2=deep(root[i-],y);
if(d1>d2)x^=y^=x^=y;insert(root[i],root[i-],x,y,,n);
if(d1==d2)update(root[i],y);
break;
case :read(a),a^=ans;
root[i]=root[a];break;
case :read(a),read(b),a^=ans,b^=ans;
root[i]=root[i-];
x=find_root(root[i],a),y=find_root(root[i],b);
if(x==y)puts(""),ans=;
else puts(""),ans=;
break;
}
}
}
int main(){
Init();
Work();
return ;
}
【BZOJ3674】可持久化并查集加强版的更多相关文章
- bzoj3673可持久化并查集 by zky&&bzoj3674可持久化并查集加强版
bzoj3673可持久化并查集 by zky 题意: 维护可以恢复到第k次操作后的并查集. 题解: 用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以 ...
- BZOJ3674: 可持久化并查集加强版
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3674 题解:主要是可持久化的思想.膜拜了一下hzwer的代码后懂了. 其实本质是可持久化fa数 ...
- 2019.01.21 bzoj3674: 可持久化并查集加强版(主席树+并查集)
传送门 题意:维护可持久化并查集,支持在某个版本连边,回到某个版本,在某个版本 询问连通性. 思路: 我们用主席树维护并查集fafafa数组,由于要查询历史版本,因此不能够用路径压缩. 可以考虑另外一 ...
- [BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky
思路: 用主席树维护并查集森林,每次连接时新增结点. 似乎并不需要启发式合并,我随随便便写了一个就跑到了3674第一页?3673是这题的弱化版,本来写个暴力就能过,现在借用加强版的代码(去掉异或),直 ...
- BZOJ3674 可持久化并查集加强版 可持久化 并查集
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3674 题意概括 n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的 ...
- 【BZOJ3673/3674】可持久化并查集/可持久化并查集加强版 可持久化线段树
[BZOJ3674]可持久化并查集加强版 Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了! ...
- 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 用可持久化线段树维护可持久化数组从而实现可持 ...
- bzoj3674 可持久化并查集
我是萌萌的任意门 可持久化并查集的模板题-- 做法好像很多,可以标号法,可以森林法. 本来有O(mloglogn)的神算法(按秩合并+倍增),然而我这种鶸渣就只会写O(mlog2n)的民科算法--再加 ...
随机推荐
- 如何用Python做自动化特征工程
机器学习的模型训练越来越自动化,但特征工程还是一个漫长的手动过程,依赖于专业的领域知识,直觉和数据处理.而特征选取恰恰是机器学习重要的先期步骤,虽然不如模型训练那样能产生直接可用的结果.本文作者将使用 ...
- C语言Windows程序开发—Windows窗口样式与常用控件样式【第04天】
(一)Windows窗口(MDICLIENT)样式介绍 /* Windows窗口样式 */ WS_BORDER //带有边框的窗口 WS_CAPTION //带有标题栏的窗口 WS_CHILD //子 ...
- C语言运算符优先级和结合性
运算符优先级和结合性 优先级 运算符 结合性 ...
- python2.7入门--- 日期和时间
Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能.我们今天就来看一下这方面,首先得知道,Python 提供了一个 time 和 calendar 模块可以用于格式化日 ...
- C 二维指针难点详解。
关于 指向二维数组的指针. int a[2][3]; int *p; int (*p_1)[3]; 可以用p_1 = a ,但是不能用p = a : 因为此时数组a的数据类型是 int (* ...
- C++语言入门知识点(详细版)【持续更新每周三更】,小舒舒戳这里!!!
时间过得好快啊,LITTLESUN已经在这块新地图摸打滚爬了一个多月了.前一段时间出了点小意外一直没能更新博客,昨天被小舒舒催更了(惭愧惭愧)便准备着手来一篇回忆录回首一下这一个月走过的风风雨雨,也希 ...
- itop-4412开发板学习-内核信号量
1. 翻翻书看下,linux提供两种信号量,内核信号量,由内核控制路径使用,System V IPC信号量,由用户态进程使用.下面的就是内核部分的信号量.内核信号量类似于自旋锁,当锁关闭着时,不允许内 ...
- golang log
自带log模块 写入文件 package main import ( "fmt" "log" "os" ) func main(){ log ...
- SQL的鸡肋:“视图”
不知道当年SQL定义者们设计视图时是出于什么样的考虑.实际效果是,视图夹在SQL指令和表之间,形成了一个三明治的结构.在这种结构下做检索,SQL指令每次都要通过视图转换,才能作用到表上.如果不 ...
- 第5讲——cin处理字符输入
本来这一讲应该是while.for.if之类的,但是,我们可是学过C的男人,再浪费时间搞这个??? 还不如学点C++中的新知识. cin对象支持3种不同模式的单字符输入,其用户接口各不相同. 下面我们 ...