bzoj 3674 可持久化并查集加强版
题目大意:
n个集合 m个操作 操作有三种(强制在线):
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
思路:
因为每次只会改一个点的$fa$,可以使用主席树暴力维护,$find$的时候不路径压缩 暴力跳
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #define ll long long 12 #define db double 13 #define inf 2139062143 14 #define MAXN 200100 15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i) 16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i) 17 #define ren for(register int i=fst[x];i;i=nxt[i]) 18 #define pb(i,x) vec[i].push_back(x) 19 #define pls(a,b) (a+b)%MOD 20 #define mns(a,b) (a-b+MOD)%MOD 21 #define mul(a,b) (1LL*(a)*(b))%MOD 22 using namespace std; 23 inline int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 27 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 28 return x*f; 29 } 30 int n,m,rt[MAXN],ls[MAXN<<5],rs[MAXN<<5],rk[MAXN<<5],fa[MAXN<<5]; 31 int tot,las; 32 void build(int &k,int l,int r) 33 { 34 k=++tot;if(l==r) {fa[k]=l;return ;}int mid=l+r>>1; 35 build(ls[k],l,mid);build(rs[k],mid+1,r); 36 } 37 void mdf(int &k,int kk,int l,int r,int x,int pa) 38 { 39 k=++tot;if(l==r) {rk[k]=rk[kk],fa[k]=pa;return ;}int mid=l+r>>1; 40 if(x<=mid) rs[k]=rs[kk],mdf(ls[k],ls[kk],l,mid,x,pa); 41 else ls[k]=ls[kk],mdf(rs[k],rs[kk],mid+1,r,x,pa); 42 } 43 void add(int k,int l,int r,int x) 44 { 45 if(l==r) {rk[k]++;return ;}int mid=l+r>>1; 46 x<=mid?add(ls[k],l,mid,x):add(rs[k],mid+1,r,x) ; 47 } 48 int query(int k,int l,int r,int x) 49 { 50 if(l==r) return k;int mid=l+r>>1; 51 return x<=mid?query(ls[k],l,mid,x):query(rs[k],mid+1,r,x); 52 } 53 int find(int id,int x){int pos=query(rt[id],1,n,x);return x==fa[pos]?x:find(id,fa[pos]);} 54 void merge(int id,int x,int y) 55 { 56 int f1=find(id,x),f2=find(id,y);if(f1==f2) return ; 57 if(rk[f1]<rk[f2]) swap(f1,f2);mdf(rt[id],rt[id-1],1,n,f2,f1); 58 if(rk[f1]==rk[f2]) add(rt[id],1,n,f1); 59 } 60 int main() 61 { 62 n=read(),m=read();build(rt[0],1,n);int c,a,b; 63 rep(i,1,m) 64 { 65 c=read(),a=read()^las,rt[i]=rt[i-1]; 66 if(c==1) b=read()^las,merge(i,a,b); 67 else if(c&1) b=read()^las,puts((las=(find(i,a)==find(i,b)))?"1":"0"); 68 else rt[i]=rt[a]; 69 } 70 }