可持久化並查集模板
阿新 • • 發佈:2020-08-22
測試題目
洛谷模板題傳送門
Code:
//By zuiyumeng #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define Re register #define Ms(a,b) memset((a),(b),sizeof(a)) #define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++) #define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();} while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar(); return x*f; } const int N=100010; int n,m,cnt; int fa[N*20],root[N*20],ls[N*20],rs[N*20],dep[N*20]; #define mid ((l+r)>>1) void build(int &cur,int l,int r) { cur=++cnt; if(l==r) {fa[cur]=l;return ;} build(ls[cur],l,mid); build(rs[cur],mid+1,r); } void merge(int las,int &cur,int l,int r,int u,int v) { cur=++cnt; ls[cur]=ls[las]; rs[cur]=rs[las]; if(l==r) fa[cur]=v,dep[cur]=dep[las]; else if(u<=mid) merge(ls[las],ls[cur],l,mid,u,v); //注意las和cur跟著一起跳 else merge(rs[las],rs[cur],mid+1,r,u,v); } void update(int cur,int l,int r,int u) { if(l==r) dep[cur]++; else if(u<=mid) update(ls[cur],l,mid,u); else update(rs[cur],mid+1,r,u); } int getnm(int cur,int l,int r,int u) { if(l==r) return cur; else if(u<=mid) return getnm(ls[cur],l,mid,u); else return getnm(rs[cur],mid+1,r,u); } int getro(int rt,int u) { int num=getnm(rt,1,n,u); return fa[num]==u?num:getro(rt,fa[num]); //注意這裡返回的是num,因為對應值可以由fa[num]得到 } int main() { n=read(); m=read(); build(root[0],1,n); Fo(i,1,m) { int opt=read(); if(opt==1) { int u=read(),v=read(); int ru=getro(root[i-1],u),rv=getro(root[i-1],v); if(dep[ru]>dep[rv]) swap(ru,rv); merge(root[i-1],root[i],1,n,fa[ru],fa[rv]); if(dep[ru]==dep[rv]) update(root[i],1,n,fa[rv]); } else if(opt==2) root[i]=root[read()]; else { int u=read(),v=read(); root[i]=root[i-1]; int ru=getro(root[i],u),rv=getro(root[i],v); if(ru==rv) cout<<1<<endl; else cout<<0<<endl; } } return 0; }