BZOJ3673 可持久化并查集 by zky 【主席树】
BZOJ3673 可持久化并查集 by zky
Description
n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
0<n,m<=2∗104" role="presentation" style="position: relative;">0<n,m<=2∗1040<n,m<=2∗104
Sample Input
5 6
1 1 2
3 1 2
2 0
3 1 2
2 1
3 1 2
Sample Output
1
0
1
就是并查集吗,只需要可持久化一个数组就完了
然后主席树可以很方便地实现
模拟一下并查集操作模式就好了
#include<bits/stdc++.h>
using namespace std;
#define N 200010
int n,m,tot=0;
int rt[N],ls[N],rs[N],val[N],dep[N];
void build(int &t,int l,int r){
if(l>r)return;
t=++tot;
if(l==r){val[t]=l;dep[t]=1;return;}
int mid=(l+r)>>1;
build(ls[t],l,mid);
build(rs[t],mid+1,r);
}
void modify(int &t,int last,int l,int r,int pos,int vl){
t=++tot;
if(l==r){val[t]=vl;dep[t]=dep[last];return;}
ls[t]=ls[last];
rs[t]=rs[last];
int mid=(l+r)>>1;
if(pos<=mid)modify(ls[t],ls[last],l,mid,pos,vl);
else modify(rs[t],rs[last],mid+1,r,pos,vl);
}
int query(int t,int l,int r,int pos){
if(l==r)return t;
int mid=(l+r)>>1;
if(pos<=mid)return query(ls[t],l,mid,pos);
else return query(rs[t],mid+1,r,pos);
}
void add(int t,int l,int r,int pos){
if(l==r){dep[t]++;return;}
int mid=(l+r)>>1;
if(pos<=mid)add(ls[t],l,mid,pos);
else add(rs[t],mid+1,r,pos);
}
int find(int t,int x){
int p=query(t,1,n,x);
if(x==val[p])return p;
return find(t,val[p]);
}
int main(){
scanf("%d%d",&n,&m);
build(rt[0],1,n);
for(int i=1;i<=m;i++){
int op,x,y;scanf("%d",&op);
if(op==1){
rt[i]=rt[i-1];
scanf("%d%d",&x,&y);
int fax=find(rt[i],x);
int fay=find(rt[i],y);
if(val[fax]==val[fay])continue;
if(dep[fax]>dep[fay])swap(fax,fay);
modify(rt[i],rt[i-1],1,n,val[fax],val[fay]);
if(dep[fax]==dep[fay])add(rt[i],1,n,val[fay]);
}else if(op==2){
scanf("%d",&x);
rt[i]=rt[x];
}else if(op==3){
rt[i]=rt[i-1];
scanf("%d%d",&x,&y);
int fax=find(rt[i],x);
int fay=find(rt[i],y);
if(val[fax]==val[fay])printf("1\n");
else printf("0\n");
}
}
return 0;
}
BZOJ3673 可持久化并查集 by zky 【主席树】的更多相关文章
- Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Description n个集合 m个操作 操作: 1 a b 合并a,b所在集 ...
- bzoj3673可持久化并查集 by zky&&bzoj3674可持久化并查集加强版
bzoj3673可持久化并查集 by zky 题意: 维护可以恢复到第k次操作后的并查集. 题解: 用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以 ...
- BZOJ 3674 可持久化并查集加强版(主席树变形)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [Submit][Sta ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- 2019.01.21 bzoj3674: 可持久化并查集加强版(主席树+并查集)
传送门 题意:维护可持久化并查集,支持在某个版本连边,回到某个版本,在某个版本 询问连通性. 思路: 我们用主席树维护并查集fafafa数组,由于要查询历史版本,因此不能够用路径压缩. 可以考虑另外一 ...
- [bzoj3673] 可持久化并查集 by zky
总感觉到现在才来写这题有点奇怪. 并查集如果按秩合并的话,每次合并只会修改一个点的父亲. 用可持久化线段树来实现可持久化数组就行了.. 然而我写的是按子树大小合并..结果比按秩合并慢了一点>_& ...
- [BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky
思路: 用主席树维护并查集森林,每次连接时新增结点. 似乎并不需要启发式合并,我随随便便写了一个就跑到了3674第一页?3673是这题的弱化版,本来写个暴力就能过,现在借用加强版的代码(去掉异或),直 ...
- bzoj3673: 可持久化并查集 by zky&&3674: 可持久化并查集加强版
主席树可持久化数组,还挺好YY的 然而加强版要路径压缩.. 发现压了都RE 结果看了看数据,默默的把让fx的父亲变成fy反过来让fy的父亲变成fx 搞笑啊 #include<cstdio> ...
- BZOJ3673 可持久化并查集 by zky 可持久化 并查集
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3673 题意概括 n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的 ...
随机推荐
- python中的上下文管理器
刚刚看了vamei大神的上下文管理器博客,理解如下: 其实我自己经常用到上下文管理器,尤其是在打开文件的时候,如果自己比较懒,不想手工打上f.close(),使用上下文管理器就ok拉. 上下文管理器就 ...
- linux下增加useradd提示existing lock file /etc/subgid.lock without a PID
# useradd git -g git useradd: existing lock file /etc/subgid.lock without a PID useradd: cannot lock ...
- Python类变量,实例变量,类方法,实例方法,静态方法的分析
Python作为动态语言,跟静态语言如c/c++有很大区别,其中的一个重要的特性就是Python的变量无需声明直接可用.同样,类的成员变量无需声明,直接可用.目的是为了动态语言跟灵活,在思路想到的时候 ...
- Linux系统用户及用户组管理
目录一.新增/删除用户和用户组二.创建/修改密码三.用户身份切换--su和sudo 一.新增/删除用户和用户组1.用户组 命令 : groupadd 语法 : groupadd [-g GID] gr ...
- Apache的三种工作模式及相关配置
Apache的三种工作模式 作为老牌服务器,Apache仍在不断地发展,就目前来说,它一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块).它们分别是 prefor ...
- 16.并发容器之CopyOnWriteArrayList
1. CopyOnWriteArrayList的简介 java学习者都清楚ArrayList并不是线程安全的,在读线程在读取ArrayList的时候如果有写线程在写数据的时候,基于fast-fail机 ...
- 1-22-shell脚本的基础
1.1 shell 脚本的编写规范 1.2 变量与特殊变量应用 1.3局部变量与全局变量 1.4 条件测试表达式 ------------------------------------------- ...
- nyoj117——树状数组升级版(树状数组+离散化)
求逆序数 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中 ...
- javascript curry 柯里化函数 仿lodash的curry
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- php中mysql_fetch_row() 和mysql_fetch_array之间有什么区别
mysql_fetch_row是从结果集取出1行数组,作为枚举 mysql_fetch_array是从结果集取出一行数组作为关联数组,或数字数组,两者兼得eg:$sql="select ab ...