首页 > 其他 > 详细

可持久化数据结构学习笔记

时间:2018-04-20 14:13:13      阅读:189      评论:0      收藏:0      [点我收藏+]

学习了一段时间的可持久化数据结构,感觉自己的脑子不太够用。。。。

好吧,先从最基本的看起

可持久化数组

题目链接

你需要维护这样的一个长度为 N 的数组,支持如下几种操作

1.在某个历史版本上修改某一个位置上的值

2.访问某个历史版本上的某一位置的值

此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组)

 

一个很暴力的想法是将所有的版本都存下来,然后每次修改是复制一遍

这样可以O(1)查询,但是要O(N)修改,而且空间复杂度。。。。。

可以发现每次修改只会对一个位置产生影响,那我们为什么每次都要讲所有的位置进行复制呢?

我们利用可持久化线段树来解决可持久化数组的问题

维护n个单点修改单点查询的线段树

为了利用重复的空间

每次修改时,我们就创立一个新的节点

然后使得新的根可以访问到该节点

这样就实现了可持久化数组

right,left数组储存左右儿子的编号,t数组储存线段树节点的信息

r数组储存根节点的编号

不同的根节点可以访问不同的版本

注意一下,right,left,t数组一般空间都要开到20到30倍

 

# include<cstring>
# include<iostream>
# include<cstdio>
# include<cmath>
# include<algorithm>
const int mn = 1000005;
int n,m;
int cnt;
int left[mn*20],right[mn*20],r[mn],t[mn*20];
int build(int l,int r)
{
     int root=++cnt;
     if(l==r)
     {
         scanf("%d",&t[root]);
         return root;
     }
     int mid=l+r>>1;
     left[root]=build(l,mid);
     right[root]=build(mid+1,r);
     return root;
}
void query(int rt,int l,int r,int x)
{
    if(l==r)
    {
        printf("%d\n",t[rt]);
        return ;
    }
    int mid=l+r>>1;
    if(x<=mid)
       query(left[rt],l,mid,x);
    else query(right[rt],mid+1,r,x);
}
int update(int rt,int l,int r,int pos,int x)
{
    int root=++cnt;
    if(l==r)
    {
        t[root]=x;
        return root;
    }
    left[root]=left[rt],right[root]=right[rt];
    int mid=l+r>>1;
    if(pos<=mid)
       left[root]=update(left[rt],l,mid,pos,x);
    else right[root]=update(right[rt],mid+1,r,pos,x);
    return root;
}
int main()
{
    int x,y,opt,z;
    scanf("%d%d",&n,&m);
    build(1,n);
    r[0]=1;
    for(int i=1;i<=m;i++)
    {
       scanf("%d%d",&x,&opt);
       if(opt==1)
       {
           scanf("%d%d",&y,&z);
           r[i]=update(r[x],1,n,y,z);
       }
       else {
          scanf("%d",&y);
          r[i]=r[x];
          query(r[x],1,n,y);
       }
    }
    return 0;
}

 

博主是弱弱,不对的地方还请神犇指出

 

可持久化数据结构学习笔记

原文:https://www.cnblogs.com/logeadd/p/8890374.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!