隨便地點開了這道可持久化並查集,發現了真相...這和並查集有 PI 關係哦.除了find_father(並且還不能路徑壓縮),全都是線段樹0.0ios
題目連接: luogu.orggit
題目沒什麼描述,就是三個操做:ui
1. 合併 a bspa
2. 回到第 k 步操做(三個操做均算操做)code
3. 查詢 a b 在當前版本的並查集中是否在同一棵樹中blog
那麼...get
對於操做 1 :咱們在線段樹中修改節點 fa 的父親爲 fbstring
對於操做 2 :簡單,咱們直接把當前版本的根指向第 k 版本的根,一行就解決了(引發可持久化的罪魁禍首解決卻是簡單)it
對於操做 3 :查詢 fa 和 fb 輸出就行了(貌似就操做 1 有點很差理解)io
對於操做 1 ,模擬如圖:
代碼以下:
1 //by Judge 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #define ls ch[now][0] 7 #define rs ch[now][1] 8 #define mid (l+r>>1) 9 #define swap(a,b) (a)^=(b)^=(a)^=(b) 10 using namespace std; 11 const int M=2e5+11; 12 inline int read(){ 13 int x=0,f=1; char c=getchar(); 14 for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; 15 for(;isdigit(c);c=getchar()) x=x*10+c-'0'; 16 return x*f; 17 } 18 int n,m,cnt; 19 int ed[M<<5],f[M<<5],ch[M<<5][2],dep[M<<5]; 20 inline void build(int& now,int l,int r){ //建樹,葉子節點認 左(右)端點 爲父親 21 now=++cnt; if(l==r){ f[now]=l; return ; } 22 build(ls,l,mid), build(rs,mid+1,r); 23 } 24 void update(int& now,int las,int l,int r,int pos,int fa){ //修改 pos 的父親爲 fa 25 now=++cnt; if(l==r){ f[now]=fa,dep[now]=dep[las]; return ; } 26 if(pos<=mid) update(ls,ch[las][0],l,mid,pos,fa); 27 else update(rs,ch[las][1],mid+1,r,pos,fa); 28 } 29 int query(int now,int l,int r,int pos){ //詢問在 now 版本中 pos 的節點編號 30 if(l==r) return now; 31 if(pos<=mid) return query(ls,l,mid,pos); 32 else return query(rs,mid+1,r,pos); 33 } 34 void add(int now,int l,int r,int pos){ //增長 now 版本中 pos 所在葉子節點的深度 35 if(l==r) { ++dep[now]; return ; } 36 if(pos<=mid) add(ls,l,mid,pos); 37 else add(rs,mid+1,r,pos); 38 } 39 int find(int ed,int x){ //查詢祖先 40 int fa=query(ed,1,n,x); 41 if(x==f[fa]) return fa; 42 return find(ed,f[fa]); 43 } 44 int main(){ 45 n=read(),m=read(),build(ed[0],1,n); 46 for(int i=1,opt,a,b,f1,f2;i<=m;++i) 47 switch(opt=read()){ 48 case 1: //不顯然 49 ed[i]=ed[i-1],a=read(),b=read(); 50 f1=find(ed[i],a),f2=find(ed[i],b); 51 if(f[f1]==f[f2]) break; 52 if(dep[f1]>dep[f2]) swap(f1,f2); 53 update(ed[i],ed[i-1],1,n,f[f1],f[f2]); 54 if(dep[f1]==dep[f2]) add(ed[i],1,n,f[f2]); break; //這裏 emmm,看上文 55 case 2: //顯然 56 ed[i]=ed[read()]; break; 57 case 3: //顯然 58 ed[i]=ed[i-1],a=read(),b=read(); 59 f1=find(ed[i],a), f2=find(ed[i],b); 60 puts(f[f1]==f[f2]?"1":"0"); break; 61 } 62 return 0; 63 }
上面代碼可能出鍋,下面代碼應該沒毛病...
1 //by Judge 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #define ls ch[now][0] 7 #define rs ch[now][1] 8 #define mid (l+r>>1) 9 #define swap(a,b) (a)^=(b)^=(a)^=(b) 10 using namespace std; 11 const int M=2e5+11; 12 inline int read(){ 13 int x=0,f=1; char c=getchar(); 14 for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; 15 for(;isdigit(c);c=getchar()) x=x*10+c-'0'; 16 return x*f; 17 } 18 int n,m,cnt; 19 int ed[M<<5],f[M<<5],ch[M<<5][2],dep[M<<5]; 20 inline void build(int& now,int l,int r){ 21 now=++cnt; if(l==r){ f[now]=l; return ; } 22 build(ls,l,mid), build(rs,mid+1,r); 23 } 24 void update(int& now,int las,int l,int r,int pos,int fa){ 25 now=++cnt; if(l==r){ f[now]=fa,dep[now]=dep[las]; return ; } 26 ls=ch[las][0], rs=ch[las][1]; 27 if(pos<=mid) update(ls,ch[las][0],l,mid,pos,fa); 28 else update(rs,ch[las][1],mid+1,r,pos,fa); 29 } 30 int query(int now,int l,int r,int pos){ 31 if(l==r) return now; 32 if(pos<=mid) return query(ls,l,mid,pos); 33 else return query(rs,mid+1,r,pos); 34 } 35 void add(int now,int l,int r,int pos){ 36 if(l==r) { ++dep[now]; return ; } 37 if(pos<=mid) add(ls,l,mid,pos); 38 else add(rs,mid+1,r,pos); 39 } 40 int find(int ed,int x){ 41 int fa=query(ed,1,n,x); 42 if(x==f[fa]) return fa; 43 return find(ed,f[fa]); 44 } 45 int main(){ 46 n=read(),m=read(),build(ed[0],1,n); 47 for(int i=1,opt,a,b,f1,f2;i<=m;++i) 48 switch(opt=read()){ 49 case 1: 50 ed[i]=ed[i-1],a=read(),b=read(); 51 f1=find(ed[i],a),f2=find(ed[i],b); 52 if(f[f1]==f[f2]) break; 53 if(dep[f1]>dep[f2]) swap(f1,f2); 54 update(ed[i],ed[i-1],1,n,f[f1],f[f2]); 55 if(dep[f1]==dep[f2]) add(ed[i],1,n,f[f2]); break; 56 case 2: ed[i]=ed[read()]; break; 57 case 3: 58 ed[i]=ed[i-1],a=read(),b=read(); 59 f1=find(ed[i],a), f2=find(ed[i],b); 60 puts(f[f1]==f[f2]?"1":"0"); break; 61 } 62 return 0; 63 }
by Judge