bzoj3673可持久化并查集 by zky

题意:

维护可以恢复到第k次操作后的并查集。

题解:

用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以使合并均摊复杂度为O(nlog2n)。可持久化线段树实际上就是在更新节点时按主席树的插入方式新建一条路径(其实主席树就是可持久化权值线段树)。

代码:

 #include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 30000
#define inc(i,j,k) for(int i=j;i<=k;i++)
using namespace std; int fa[maxn*],ch[maxn*][],dep[maxn*],pos[maxn*],sz,n,m,rt[maxn];
inline int read(){
char ch=getchar(); int f=,x=;
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();} while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return f*x;
}
void build(int &x,int l,int r){
x=++sz; if(l==r){fa[x]=l; dep[x]=; pos[x]=l; return;}
int mid=(l+r)>>; build(ch[x][],l,mid); build(ch[x][],mid+,r);
}
void updatefa(int &x,int l,int r,int a,int b){
sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][]=ch[x][]; ch[sz][]=ch[x][];
x=sz; if(l==r){fa[x]=b; return;}
int mid=(l+r)>>; if(a<=mid)updatefa(ch[x][],l,mid,a,b);else updatefa(ch[x][],mid+,r,a,b);
}
void updatedep(int &x,int l,int r,int a,int b){
sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][]=ch[x][]; ch[sz][]=ch[x][];
x=sz; if(l==r){dep[x]=b; return;}
int mid=(l+r)>>; if(a<=mid)updatedep(ch[x][],l,mid,a,b);else updatedep(ch[x][],mid+,r,a,b);
}
int query(int x,int l,int r,int a){
if(l==r)return x; int mid=(l+r)>>;
if(a<=mid)return query(ch[x][],l,mid,a);else return query(ch[x][],mid+,r,a);
}
int find(int x,int y){
int z=query(x,,n,y); if(fa[z]==pos[z])return z;else return find(x,fa[z]);
}
void merge(int &s,int x,int y){
int z1=find(s,x),z2=find(s,y); if(pos[z1]==pos[z2])return; if(dep[z1]>dep[z2])swap(z1,z2);
int abc=max(dep[z2],dep[z1]+); updatefa(s,,n,pos[z1],pos[z2]); updatedep(s,,n,pos[z2],abc);
}
int main(){
n=read(); m=read(); build(rt[],,n);
inc(i,,m){
int opt=read();
if(opt==){int a=read(),b=read(); rt[i]=rt[i-]; merge(rt[i],a,b);}
if(opt==){int k=read(); rt[i]=rt[k];}
if(opt==){
int a=read(),b=read(); rt[i]=rt[i-];
if(pos[find(rt[i],a)]==pos[find(rt[i],b)])puts("");else puts("");
}
}
return ;
}

------------------------------------------------------------------------------------------------------------------------------------------

bzoj3674可持久化并查集加强版

题意:

同3673,但强制在线且点数操作数≤200000

题解:

T个不停,后来看黄学长博客把数组n*2(log2n)开成结果A了,后来突然明白我fa数组和dep数组是分开维护的,也就是说每次操作新建了两条路径,当然要*2,QAQ~

代码:

 #include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 200010
#define inc(i,j,k) for(int i=j;i<=k;i++)
using namespace std; int fa[maxn*],ch[maxn*][],dep[maxn*],pos[maxn*],sz,n,m,rt[maxn];
inline int read(){
char ch=getchar(); int f=,x=;
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();} while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return f*x;
}
void build(int &x,int l,int r){
x=++sz; if(l==r){fa[x]=l; dep[x]=; pos[x]=l; return;}
int mid=(l+r)>>; build(ch[x][],l,mid); build(ch[x][],mid+,r);
}
void updatefa(int &x,int l,int r,int a,int b){
sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][]=ch[x][]; ch[sz][]=ch[x][];
x=sz; if(l==r){fa[x]=b; return;}
int mid=(l+r)>>; if(a<=mid)updatefa(ch[x][],l,mid,a,b);else updatefa(ch[x][],mid+,r,a,b);
}
void updatedep(int &x,int l,int r,int a,int b){
sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][]=ch[x][]; ch[sz][]=ch[x][];
x=sz; if(l==r){dep[x]=b; return;}
int mid=(l+r)>>; if(a<=mid)updatedep(ch[x][],l,mid,a,b);else updatedep(ch[x][],mid+,r,a,b);
}
int query(int x,int l,int r,int a){
if(l==r)return x; int mid=(l+r)>>;
if(a<=mid)return query(ch[x][],l,mid,a);else return query(ch[x][],mid+,r,a);
}
int find(int x,int y){
int z=query(x,,n,y); if(fa[z]==pos[z])return z;else return find(x,fa[z]);
}
void merge(int &s,int x,int y){
int z1=find(s,x),z2=find(s,y); if(pos[z1]==pos[z2])return; if(dep[z1]>dep[z2])swap(z1,z2);
int abc=max(dep[z2],dep[z1]+); updatefa(s,,n,pos[z1],pos[z2]); updatedep(s,,n,pos[z2],abc);
}
int main(){
n=read(); m=read(); build(rt[],,n); int last=;
inc(i,,m){
int opt=read();
if(opt==){int a=read()^last,b=read()^last; rt[i]=rt[i-]; merge(rt[i],a,b);}
if(opt==){int k=read()^last; rt[i]=rt[k];}
if(opt==){
int a=read()^last,b=read()^last; rt[i]=rt[i-];
if(pos[find(rt[i],a)]==pos[find(rt[i],b)])puts(""),last=;else puts(""),last=;
}
}
return ;
}

20160623

bzoj3673可持久化并查集 by zky&&bzoj3674可持久化并查集加强版的更多相关文章

  1. [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  2. bzoj3673: 可持久化并查集 by zky&&3674: 可持久化并查集加强版

    主席树可持久化数组,还挺好YY的 然而加强版要路径压缩.. 发现压了都RE 结果看了看数据,默默的把让fx的父亲变成fy反过来让fy的父亲变成fx 搞笑啊 #include<cstdio> ...

  3. 【BZOJ 3674】可持久化并查集加强版&【BZOJ 3673】可持久化并查集 by zky 用可持久化线段树破之

    最后还是去掉异或顺手A了3673,,, 并查集其实就是fa数组,我们只需要维护这个fa数组,用可持久化线段树就行啦 1:判断是否属于同一集合,我加了路径压缩. 2:直接把跟的值指向root[k]的值破 ...

  4. 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  5. BZOJ3673 可持久化并查集 by zky 【主席树】

    BZOJ3673 可持久化并查集 by zky Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a ...

  6. 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树

    没什么好说的. 可持久化线段树,叶子节点存放父亲信息,注意可以规定编号小的为父亲. Q:不是很清楚空间开多大,每次询问父亲操作后修改的节点个数是不确定的.. #include<bits/stdc ...

  7. 3673: 可持久化并查集 by zky

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 2170  Solved: 978[Submit][Status ...

  8. Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)

    3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Description n个集合 m个操作 操作: 1 a b 合并a,b所在集 ...

  9. bzoj 3673&3674: 可持久化并查集 by zky

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

随机推荐

  1. 基于JQuery的简单富文本编辑器

    利用jQuery实现最简单的编辑器 我试了很多种方法,目前最快捷能够实现及其简单的编辑可以使用 document.execCommand("ForeColor", "fa ...

  2. python基础003----标准数据类型

    一.标准数据类型 在python中,只要定义了一个变量,而且它有数据,那么它的类型就已经确定了,不需要开发者主动去说明它的类型,系统会自动识别.可以用type(变量名)来查看变量的类型.常见的变量类型 ...

  3. 消息队列——Kafka基本使用及原理分析

    文章目录 一.什么是Kafka 二.Kafka的基本使用 1. 单机环境搭建及命令行的基本使用 2. 集群搭建 3. Java API的基本使用 三.Kafka原理浅析 1. topic和partit ...

  4. 关于HTTP 请求方式: GET和POST的比较的本质

    什么是HTTP? 超文本传输协议(HyperText Transfer Protocol -- HTTP)是一个设计来使客户端和服务器顺利进行通讯的协议. HTTP在客户端和服务器之间以request ...

  5. Elasticsearch、Solr、Lucene、Hermes区别

    Elasticsearch简介 Elasticsearch是一个实时分布式搜索和分析引擎.它让你以前所未有的速度处理大数据成为可能.它用于全文搜索.结构化搜索.分析以及将这三者混合使用:维基百科使用E ...

  6. 第七模块 :微服务监控告警Prometheus架构和实践

    119.监控模式分类~1.mp4 logging:日志监控,Logging 的特点是,它描述一些离散的(不连续的)事件. 例如:应用通过一个滚动的文件输出 Debug 或 Error 信息,并通过日志 ...

  7. Idea中SpringBoot整合JSP

    最近在学习SpringBoot,看到SpringBoot整合jsp,顺带记录一下. 1.创建一个SpringBoot项目 点击Next 注意:packaging选中War,点击Next Webà选中W ...

  8. egret.sys.TextNode

    class Test extends egret.Shape{ protected textNode:egret.sys.TextNode; constructor(){ this.width = t ...

  9. YoyoGo基于ASP.NET Core设计的Golang实现

    YoyoGo YoyoGo 是一个用 Go 编写的简单,轻便,快速的 微服务框架,目前已实现了Web框架的能力,但是底层设计已支持. Github https://github.com/yoyofx/ ...

  10. 【状压dp】Bzoj1294 围豆豆

    题目 Input 第一行两个整数N和M,为矩阵的边长. 第二行一个整数D,为豆子的总个数. 第三行包含D个整数V1到VD,分别为每颗豆子的分值. 接着N行有一个N×M的字符矩阵来描述游戏矩阵状态,0表 ...