1. 程式人生 > >可持久化並查集模板

可持久化並查集模板

#include<bits/stdc++.h>
using namespace std;

const int MAXN=1e6+2333;

int n,m;
int a[MAXN];

struct Persistable_Segment_Tree{
    struct Node{
        int val,L,R,dep;
    }t[MAXN*20];
    int cnt,rt[MAXN*20];
    void build_tree(int &root,int l,int r){
        root=++cnt;
        
if (l==r) return (void)(t[root].val=l,t[root].dep=1); int mid=l+r>>1; build_tree(t[root].L,l,mid); build_tree(t[root].R,mid+1,r); } void update(int &root,int las,int l,int r,int q,int opt){ root=++cnt; t[root]=t[las]; if (l==r) return
(void)(t[root].val=opt); int mid=l+r>>1; if (q<=mid) update(t[root].L,t[las].L,l,mid,q,opt); else update(t[root].R,t[las].R,mid+1,r,q,opt); } void add_deep(int root,int l,int r,int q){ if (l==r) return (void)(t[root].dep++); int mid=l+r>>1
; if (q<=mid) add_deep(t[root].L,l,mid,q); else add_deep(t[root].R,mid+1,r,q); } int query(int root,int l,int r,int q){ if (l==r) return root; int mid=l+r>>1; if (q<=mid) return query(t[root].L,l,mid,q); else return query(t[root].R,mid+1,r,q); } }T; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)){ if (ch=='-') f=-1; ch=getchar(); } while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f; } int find(int &rt,int x){ int tmp=T.query(rt,1,n,x); while (x!=T.t[tmp].val) x=T.t[tmp].val,tmp=T.query(rt,1,n,x); return tmp; } int main(){ n=read(),m=read(); T.cnt=0,T.build_tree(T.rt[0],1,n); int opt,x,y,u,v,dep_x,dep_y; for (int i=1;i<=m;i++){ opt=read(); if (opt==1){ // 合併集合 x=find(T.rt[i-1],read()),y=find(T.rt[i-1],read()); u=T.t[x].val,v=T.t[y].val; dep_x=T.t[x].dep,dep_y=T.t[y].dep; if (u!=v){ if (dep_x>dep_y) swap(u,v); T.update(T.rt[i],T.rt[i-1],1,n,u,v); if (dep_x==dep_y) T.add_deep(T.rt[i],1,n,v); } else T.rt[i]=T.rt[i-1]; } else if (opt==2){ // 回到歷史版本 x=read(); T.rt[i]=T.rt[x]; } else if (opt==3){ //查詢是否在同一集合 x=find(T.rt[i-1],read()),y=find(T.rt[i-1],read()); T.rt[i]=T.rt[i-1]; printf("%d\n",x!=y ? 0:1); } } return 0; }