突然想起来大家都会的可持久化并查集我还不会,所以来学一下 q w q qwq qwq
感觉可持久化并查集就是把主席树上的点的存储信息改了一下。。
其他也没什么不同的,查询一个点的父亲的时候是
l
o
g
2
n
log^2n
log2n的,修改啥的都是
l
o
g
n
logn
logn,总复杂度是
m
l
o
g
2
n
mlog^2n
mlog2n,空间是
m
l
o
g
n
mlogn
mlogn
然而,,,看了一个dalao的博客之后觉得事情有那么一点点不同,这种写法好像很快的样子,但常数有点大比不过各位卡常选手
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 200005
#define M 7400005
using namespace std;
template<class T>inline void rd(T &x){
x=0; short f=1; char c=getchar();
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
x*=f;
}
struct Data{
int ls,rs,id,val,siz;
}node[M];
int root[N],tot,w[N];
int n,m,lt,nt,ans;
void build(int x){
node[x].id=x,node[x].val=x,node[x].siz=1;
int lson=x<<1;
if(lson<=n){
node[x].ls=lson;
build(lson);
}
int rson=lson|1;
if(rson<=n){
node[x].rs=rson;
build(rson);
}
}
Data query(int cur,int L,int x){
if(x==L) return node[cur];
if(x&(1<<(w[x]-w[L]-1))) return query(node[cur].rs,L<<1|1,x);
return query(node[cur].ls,L<<1,x);
}
inline Data find(int x){
Data y=query(root[lt],1,x);
while(y.id!=y.val) y=query(root[lt],1,y.val);
return y;
}
void update(int cur,int L,int x,int tp,int v){
if(L==x){
if(tp==0) node[cur].val=v;
else node[cur].siz=v;
return;
}
if(x&(1<<(w[x]-w[L]-1))){
Data tmp=node[node[cur].rs];
node[cur].rs=++tot;
node[tot]=tmp;
update(node[cur].rs,L<<1|1,x,tp,v);
}
else {
Data tmp=node[node[cur].ls];
node[cur].ls=++tot;
node[tot]=tmp;
update(node[cur].ls,L<<1,x,tp,v);
}
}
inline void add(int x,int y){
Data fx=find(x),fy=find(y);
if(fx.siz>fy.siz) swap(fx,fy);
root[nt]=++tot;
node[tot]=node[root[lt]];
update(tot,1,fx.id,0,fy.id);
//node[++tot]=node[root[nt]],root[nt]=tot; ?
update(tot,1,fy.id,1,fx.siz+fy.siz);
}
int main(){
rd(n); rd(m); int opt,x,y;
build(1); root[1]=1; lt=nt=1; tot=n;
w[1]=1; for(int i=2;i<N;i++) w[i]=w[i>>1]+1;
while(m--){
rd(opt);
if(opt==1){
rd(x),rd(y);
nt++;
add(x,y);
lt=nt;
}
else if(opt==2){
rd(x);
nt++,lt=x+1;
root[nt]=root[lt];
lt=nt;
}
else{
rd(x),rd(y);
Data fx=find(x),fy=find(y);
if(fx.val==fy.val) puts("1"),ans=1;
else puts("0"),ans=0;
nt++,root[nt]=root[lt];
lt=nt;
}
}
return 0;
}