zoukankan      html  css  js  c++  java
  • [模板]——可持久化数组

    大概内容是要维护一个数组,支持如下操作:

    查询某个位置上的数

    修改某个位置上的数

    回到某个版本的数组(可持久化)

     

    预备知识:平衡树(非必要,了解最好),主席树

     

    为了维护这个结构,我们可以考虑使用主席树,

    建树的时候按照下标来建(维护下标),此处类似于平衡树

     

    要查询指定位置就按照找第k大,同样类似于平衡树。

    这样的话对于任意版本的线段树,我们实际上是在按照下标维护一个数列,

     

    这样修改某个位置的数就是相当于线段树的单点修改,

    跟主席树的常规操作是一样的,很好理解

     

    附一个很妙的建树方法:

    十分妙的建树方法???
     因为线段树的传统建树是十分平衡的,而线段树理论上要用到2n-1个点,
     其中n个节点是叶节点,而上面的都是区间,由于每个区间都不同,
     所以他们的mid也两两不同,why?
     感性的理解,在root的时候,mid是最中间的,
     然后往左走,因为r减小,l不变,所以mid会向左移,
     同理,往右走的时候,mid会向右移,
     因此这满足一个性质,一个点左边的mid都小于它的mid,一个点右边的mid都大于它的mid,
     因为它右边的l最小也是mid+1了,所以一个点右边的mid都大于它的mid,
     又因为它左边的r最大也是mid,在不取叶节点的情况下,由于mid会偏向左,
     因此左边的mid再大也不可能到达上面的mid那么大,
     由于对于所有节点都满足这个性质(有点类似于平衡树了),
     所以这些点的mid都是两两不同的,
     但是注意到线段树的非叶节点只有n-1个,所以还少了一个点。而这个点必然是mid=n的点,
     同样注意到对于一个区间而言,mid会偏向左,因此只要是一个区间,mid永远不可能到达n,
     所以要补上n,n这个叶节点
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define R register int 
      4 #define AC 1030100
      5 #define ac 20000100
      6 #define D printf("line in %d
    ",__LINE__);
      7 #define getchar() *o++
      8 char READ[55001000],*o=READ;
      9 int n,m,tot=1,who,ans,change;
     10 int root[AC],s[AC];
     11 struct Segament_Tree{
     12     int date,lson,rson,mid;
     13 }tree[ac];
     14 inline int read()
     15 {
     16     int x=0;char c=getchar();bool z=false;
     17     while(c > '9' || c < '0') 
     18     {
     19         if(c == '-') z=true;
     20         c=getchar();
     21     }
     22     while(c >= '0' && c <= '9') x=x*10+c-'0',c=getchar();
     23     if(!z) return x;
     24     else return -x;
     25 }
     26 
     27 void build(int x,int l,int r)//尽量平衡的建树
     28 {
     29     int mid=(l + r) >> 1;
     30     tree[x].date=s[mid];
     31     tree[x].mid=mid;
     32     if(l == r) return ;
     33     if(r - l == 1)
     34     {
     35         if(r != n) return ;
     36         else 
     37         {
     38             tree[x].rson=++tot;
     39             build(tot,r,r); 
     40         }
     41     }
     42     else
     43     {
     44         tree[x].lson=++tot;
     45         build(tot,l,mid);
     46         tree[x].rson=++tot;
     47         build(tot,mid+1,r);    
     48     }
     49 }
     50 
     51 void pre()
     52 {
     53     n=read(),m=read();
     54     for(R i=1;i<=n;i++) s[i]=read();
     55     root[0]=1;
     56 }
     57 
     58 void insert(int &now)
     59 {
     60     tree[++tot]=tree[now],now=tot;//建新节点
     61     if(tree[now].mid == who)//如果已经对应到当前节点了
     62     {
     63         tree[now].date=change;//修改
     64         return ;
     65     }
     66     else if(who < tree[now].mid) insert(tree[now].lson);
     67     else insert(tree[now].rson);
     68 }
     69 
     70 void search(int x)
     71 {
     72     if(who < tree[x].mid) search(tree[x].lson);
     73     else if(who > tree[x].mid) search(tree[x].rson);
     74     else ans=tree[x].date;
     75 }
     76 
     77 void work()
     78 {
     79     int a,tmp;
     80     for(R i=1;i<=m;i++)
     81     {
     82         tmp=read(),a=read();
     83         if(a == 1)
     84         {
     85             who=read(),change=read();
     86             root[i]=root[tmp];
     87             insert(root[i]);
     88         }
     89         else
     90         {
     91             who=read();
     92             root[i]=root[tmp];//error!!!是基于tmp的版本啊。。。。
     93             search(root[tmp]);
     94             printf("%d
    ",ans);
     95         }
     96     }
     97 }
     98 
     99 int main()
    100 {
    101 //    freopen("in.in","r",stdin);
    102     fread(READ,1,55000000,stdin);
    103     pre();
    104     build(1,1,n);
    105     work();
    106     //fclose(stdin);
    107     return 0;
    108 }
  • 相关阅读:
    Math类的用法
    c#中和java中可变参数对比
    c#中泛型集合directory和java中map集合对比
    C#调用短信接口(通过简单的工厂模式整合多个短信平台)
    C#用网易邮箱发送邮件(同步异步)
    新浪云-PHP实现上传原图,缩略图
    PHP 继承,组合,单模式,GUID,等混合实例
    ASP.Net MVC @Html类
    ASP.net MVC 无法初始化 ASP.NET Simple Membership 数据库
    PHP 单列模式实例讲解以及参考网址
  • 原文地址:https://www.cnblogs.com/ww3113306/p/9033885.html
Copyright © 2011-2022 走看看