Recommended blog:
Be persistent array: https://blog.csdn.net/chenxiaoran666/article/details/81503323
Persistable disjoint-set: https://blog.csdn.net/chenxiaoran666/article/details/81505870
https://www.cnblogs.com/peng-ym/p/9357220.html
template:
1, the array can be persistent
luogu3919:https://www.luogu.org/problem/P3919
Meaning of the questions: There is a number of columns to support the value of the $ loc $ in the original version of a query position; a modified version location for $ loc $ value of $ xx $.
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+10; 4 struct node{ 5 int l,r; int val; 6 }tree[maxn*100]; 7 int root[maxn],a[maxn],sz=0; 8 void build(int &x,int l,int r){ 9 x=++sz; 10 if (l==r){ 11 tree[x].val=a[l]; 12 return ; 13 } 14 int mid=(l+r)>>1; 15 build(tree[x].l,l,mid); 16 build(tree[x].r,mid+1,r); 17 } 18 void update(int &x,int y,int l,int r,int dex,int val){ 19 x=++sz; tree[x]=tree[y]; 20 if (l==r){ 21 tree[x].val=val; 22 return ; 23 } 24 int mid=(l+r)>>1; 25 if (dex<=mid) update(tree[x].l,tree[y].l,l,mid,dex,val); 26 else update(tree[x].r,tree[y].r,mid+1,r,dex,val); 27 } 28 int query(int x,int l,int r,int xx){ 29 if (l==r) return tree[x].val; 30 int mid=(l+r)>>1; 31 if (xx<=mid) return query(tree[x].l,l,mid,xx); 32 else return query(tree[x].r,mid+1,r,xx); 33 } 34 int main(){ 35 int n,m,v,xx,x,y;scanf("%d%d",&n,&m); 36 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 37 build(root[0],1,n); 38 for (int i=1;i<=m;i++){ 39 scanf("%d%d",&v,&xx); 40 if (xx==1){ 41 scanf("%d%d",&x,&y); 42 update(root[i],root[v],1,n,x,y); 43 } 44 else{ 45 scanf("%d",&x); 46 root[i]=root[v]; 47 int ans=query(root[i],1,n,x); 48 printf("% d \ n " , year); 49 } 50 } 51 return 0 ; 52 }
2, the persistence disjoint-set
luogu3402:https://www.luogu.org/problem/P3402
The meaning of problems: The initial there $ n-$ sets, for $ m $ operations: $ 1 ab $ merging a, b where the set; $ 2 k states (query count operation) $ back to the k th operation after; $ 3 ab $ asked a, b belong to the same collection, it is the output 1 output 0 otherwise.
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e5+10; 4 struct node{ 5 int l,r,fa,level; 6 }tree[maxn*100]; 7 int root[maxn],sz=0,n,m; 8 void build(int &x,int l,int r){ 9 x=++sz; 10 if (l==r){ 11 tree[x].fa=l; 12 return ; 13 } 14 int mid=(l+r)>>1; 15 build(tree[x].l,l,mid); 16 build(tree[x].r,mid+1,r); 17 } 18 void update(int &x,int y,int l,int r,int xx,int fa){ 19 x=++sz; tree[x]=tree[y]; 20 if (l==r){ 21 tree[x].fa=fa; 22 return ; 23 } 24 int mid=(l+r)>>1; 25 if (xx<=mid) update(tree[x].l,tree[x].l,l,mid,xx,fa); 26 else update(tree[x].r,tree[y].r,mid+1,r,xx,fa); 27 } 28 void add_level(int x,int l,int r,int xx){ 29 if (l==r){ 30 tree[x].level++; 31 return ; 32 } 33 int mid=(l+r)>>1; 34 if (xx<=mid) add_level(tree[x].l,l,mid,xx); 35 else add_level(tree[x].r,mid+1,r,xx); 36 } 37 int query(int x,int l,int r,int xx){ 38 if (l==r) return x; 39 int mid=(l+r)>>1; 40 if (xx<=mid) query(tree[x].l,l,mid,xx); 41 else query(tree[x].r,mid+1,r,xx); 42 } 43 int find(int root,int x){ //询问x在root版本下的祖先 44 int fa=query(root,1,n,x); 45 if (tree[fa].fa==x) return fa; 46 else return find(root,tree[fa].fa); 47 } 48 int main(){ 49 int xx,x,y;scanf("%d%d",&n,&m); 50 build(root[0],1,n); 51 for (int i=1;i<=m;i++){ 52 scanf("%d",&xx); 53 if (xx==1){ 54 scanf("%d%d",&x,&y); 55 root[i]=root[i-1]; 56 int fx=find(root[i],x),fy=find(root[i],y); 57 if (fx!=fy){ 58 if (tree[fx].level<tree[fy].level) swap(fx,fy); 59 update(root[i],root[i-1],1,n,tree[fy].fa,tree[fx].fa);//按秩合并 60 if (tree[fx].level==tree[fy].level) add_level(root[i],1,n,tree[fx].fa); 61 } 62 } 63 else if (xx==2){ 64 scanf("%d",&x); 65 root[i]=root[x]; 66 } 67 else{ 68 scanf("%d%d",&x,&y); 69 root[i]=root[i-1]; 70 int fx=find(root[i],x),fy=find(root[i],y); 71 if (fx==fy) printf("1\n"); else printf("0\n"); 72 } 73 } 74 return 0; 75 }