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. PDO的事务处理 事务回滚

    <?phpheader('content-type:text/html;charset=utf-8');include 'PdoClass.php';$objPdo=new PdoClass() ...

  2. SpringBoot 启动配置原理

    几个重要的事件回调机制 ApplicationContextInitializer SpringApplicationRunListener ApplicationRunner CommandLine ...

  3. 连接 mongodb 数据库 :

    mongodb  数据库: 安装 mongodb  数据库: 安装 mongodb 数据库网址: https://www.mongodb.com/download-center#community 检 ...

  4. 北京开发票/v电13543443967

    关于事项:Iㄋ5一★4З44一★ㄋ9.б7开发票的准备资料必须要公司名称个人的话就用个人名字和身份证去税务柜台申请办理!公司的话要提供公司全称就是营业执照上的名称,纳税人税号,如果是开普通增值税发票的 ...

  5. Redis 持久化-AOF自动重写配置

    AOF自动重写 auto-aof-rewrite-min-size size auto-aof-rewrite-percentage percent 在 redis.conf 自动重写的默认配置: a ...

  6. Java Service Wrapper 浅谈

    在实际开发过程中很多模块需要独立运行,他们并不会以web形式发布,传统的做法是将其压缩为jar包独立运行,这种形式简单易行也比较利于维护,但是 一旦服务器重启或出现异常时,程序往往无法自行修复或重启. ...

  7. 车辆运动控制算法——MPC

    MPC是模型预测控制算法,在车辆运动跟踪轨迹的控制中发挥很大的优势 基础的不多说,下面记录我对LQR/MPC/二次规划问题的理解 我们从LQR来引出MPC LQR的能量函数,目的是求函数J最小,即用最 ...

  8. nginx web服务器概念了解 配置

    服务器 服务器 服务器是一种提供高效计算的机器,与普通的PC主机相比,具有可观的稳定性,高并发性,可扩展性. 互联网任何一个应用都是以服务器为基础设施的,没有服务器我们就无法访问网络上的任何内容,只能 ...

  9. Python之浅谈绑定方法

    目录 绑定方法和非绑定方法 绑定方法 对象的绑定方法 类的绑定方法 非绑定方法 总结 绑定方法和非绑定方法 类中定义的方法大致可以分为两类:绑定方法和非绑定方法.其中绑定方法又可以分为绑定到对象的方法 ...

  10. Python之浅谈继承

    目录 继承 继承介绍 如何使用继承 新式类:只要继承了object类,就是新式类,再python3中,默认继承object类 经典类:没有继承object的类,就是经典类 利用继承减少代码冗余,菱形问 ...