zoukankan      html  css  js  c++  java
  • 可持久化数据结构(模板)

    推荐博客:

    可持久化数组:https://blog.csdn.net/chenxiaoran666/article/details/81503323

    可持久化并查集:https://blog.csdn.net/chenxiaoran666/article/details/81505870

    https://www.cnblogs.com/peng-ym/p/9357220.html

    模板:

    1,可持久化数组

    luogu3919:https://www.luogu.org/problem/P3919

    题意:有一个数列,支持在原来的某一版本查询位置为$loc$的值;修改某一版本位置为$loc$的值为$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
    ",ans);
    49         }
    50     }
    51     return 0;
    52 }
    可持久化数组

    2,可持久化并查集

    luogu3402:https://www.luogu.org/problem/P3402

    题意:初始有$n$个集合,进行$m$次操作:$1  a   b$合并a,b所在集合;$2   k$回到第k次操作之后的状态(查询算作操作);$3   a   b$询问a,b是否属于同一集合,是则输出1否则输出0。

     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
    "); else printf("0
    ");
    72         }
    73     }
    74     return 0;
    75 }
    可持久化并查集
  • 相关阅读:
    Java笔记(06):如何使用JDK提供的帮助文档
    Java笔记(05):面向对象--继承
    MySql:基本SQL
    Oracle:简单SQL程序、存储过程、触发器
    Oracle:批量操作、视图、序列、简单SQL程序
    力扣(LeetCode)两整数之和 个人题解
    力扣(LeetCode)买卖股票的最佳时机 个人题解
    力扣(LeetCode)环形链表 个人题解
    力扣(LeetCode)找不同 个人题解
    力扣(LeetCode)从不订购的客户-数据库题 个人题解
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11465709.html
Copyright © 2011-2022 走看看