【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)的民科算法--再加 ...
随机推荐
- git上下载的thinkphp框架报错解决方法
git上下载的thinkphp5框架使用.gitignore没上传依赖,需要通过composer进行下载依赖,使用composer install或者composer update即可解决.
- Linux 系统无法登录?你的程序有问题吧!
今天遇到一个问题,有个用户连接不上服务器(无法ssh远程连接) su: failed to execute /bin/bash: Resource temporarily unavailable 谷歌 ...
- WHERE条件中or与union引起的全表扫描的问题
说起数据库的SQL语句执行效率的问题,就不得不提where条件语句中的or(逻辑或)引起的全表扫描问题,从而导致效率下降. 在以往绝大多数的资料中,大多数人的建议是使用 union 代替 or ,以解 ...
- linux课后作业1
本实验6第一题:菜单驱动程序. 随便进到某个目录,vim driver.sh 把代码写进去. #!/bin/bash function welcome() { echo -e "\n&quo ...
- R语言学习笔记(二十):stringr包中函数介绍(表格)
stringr包中的重要函数 函数 功能说明 R Base中对应函数 使用正则表达式的函数 str_extract() 提取首个匹配模式的字符 regmatches() str_extract_all ...
- python2.7入门---文件I/O&简单用户交互
这篇文章开始之前,我们先来看下python中的输出方法.最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式.此函数把你传递的表达式转换成一个字符串表达式,并将结果写 ...
- 1 http协议
1.四层模型 + 2.socket 3.http协议 4. HTTP请求 跟踪了新浪的首页,我们来总结一下HTTP请求的流程: 3.1.1 步骤1:浏览器首先向服务器发送HTTP请求,请求包括: 方法 ...
- 大数据培训班 cloudera公司讲师面对面授课 CCDH CCAH CCP
大数据助力成就非凡.大数据正在改变着商业游戏规则,为企业解决传统业务问题带来变革的机遇.毫无疑问,当未来企业尝试分析现有海量信息以推动业务价值增值时,必定会采用大数据技术. 目前对大数据的分析工具,首 ...
- php-configure错误解决
configure: error: libjpeg.(a|so) not foundconfigure: error: libjpeg.(a|so) not foundln -sf libjpeg.s ...
- 【多校联合】(HDU6095)Rikka with Competition
题意:给定$n$个数,代表$n$个选手的能量高低,现在再给一个$k$,任意在$n$个选手中挑取两个选手比赛,如果$|a_i−a_j|>K$,那么能量高的选手获胜,另一个将被淘汰,否则两个人都有机 ...