您的位置:首页 > 其它

bzoj3674 可持久化并查集加强版

2016-01-31 15:28 190 查看

Description

Description: 自从zkysb出了可持久化并查集后…… hzwer:乱写能AC,暴力踩标程 KuribohG:我不路径压缩就过了! ndsf:暴力就可以轻松虐! zky:……
n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 请注意本题采用强制在线,所给的a,b,k均经过加密,加密方法为x = x xor lastans,lastans的初始值为0 0<n,m<=2*10^5

用可持久化满二叉查找树实现可持久化数组,每次修改记录新的根

可持久化数组实现可持久化并查集

#include<cstdio>
const int N=10000000;
int ch
[2];
int v
,id
;
int rts[200005],r;
int p=262145,la=0;
void build(int w,int s){
if(s){
build(w-s,s>>1);
build(w+s,s>>1);
ch[w][0]=w-s;
ch[w][1]=w+s;
}
v[w]=id[w]=w;
}
int get(int w,int x){
while(id[w]!=x)w=ch[w][id[w]<x];
return v[w];
}
int set(int w,int x,int y){
int u=p++;
if(id[w]==x){
ch[u][0]=ch[w][0];
ch[u][1]=ch[w][1];
v[u]=y;
}else{
bool d=id[w]<x;
ch[u][d^1]=ch[w][d^1];
ch[u][d]=set(ch[w][d],x,y);
v[u]=v[w];
}
id[u]=id[w];
return u;
}
int find(int x){
int a=x,b;
while((b=get(r,a))!=a)a=b;
while((b=get(r,x))!=a)r=set(r,x,a),x=b;
return a;
}
int n,m,o,a,b,c;
int main(){
build(rts[0]=131072,65536);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
r=rts[i-1];
scanf("%d",&o);
if(o==1){
scanf("%d%d",&a,&b);
a=find(a^la);
b=find(b^la);
rts[i]=set(r,a,b);
}else if(o==2){
scanf("%d",&a);
rts[i]=rts[a^la];
}else{
scanf("%d%d",&a,&b);
printf("%d\n",la=find(a^la)==find(b^la));
rts[i]=rts[i-1];
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: