洛谷:P3919 【模板】可持久化数组(可持久化线段树/平衡树)

原题地址:https://www.luogu.org/problemnew/show/P3919

题目简述

维护一个长度为N的数组,支持如下几种操作:

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

思路

首先感谢来自@zcysky的模板。写的非常漂亮,封装也很精致。
这题是裸题,于是直接上模板就行了。注意此题输入数据大,需要读入优化。
关于可持久化线段树的介绍与总结,之后把坑填上。


代码

#include<bits/stdc++.h>
const int N=1000005;
using namespace std;
int a[N],n,q,rt[N*20];//空间复杂度O(mlogn) 
#define MAXB 50000000
char buf[MAXB],*cp=buf;
inline int read()
{
    int f=1,x=0;
    while(*cp<'0'||*cp>'9') {
        if(*cp=='-')
            f=-1;
        cp++;
    }
    while(*cp>='0'&&*cp<='9') {
        x=x*10+*cp-'0'; 
        cp++;
    }
    return f*x;
}
struct Persistable_Segment_Tree {
    int lc[N*20],rc[N*20],val[N*20],cnt;
    inline void build(int &o,int l,int r){
        o=++cnt;
        if(l==r) {
            val[o]=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(lc[o],l,mid);
        build(rc[o],mid+1,r);
    }
    inline void ins(int &o,int pre,int l,int r,int q,int v){
        o=++cnt;
        lc[o]=lc[pre];
        rc[o]=rc[pre];
        val[o]=val[pre];
        if(l==r) {
            val[o]=v;
            return;
        }
        int mid=(l+r)>>1;
        if(q<=mid)
            ins(lc[o],lc[pre],l,mid,q,v);
        else 
            ins(rc[o],rc[pre],mid+1,r,q,v);
    }
    inline int query(int o,int l,int r,int q){//类似二分的查询 
        if(l==r)
            return val[o];
        int mid=(l+r)>>1;
        if(q<=mid)
            return query(lc[o],l,mid,q);
        else 
            return query(rc[o],mid+1,r,q);
    }
}T;
int main()
{
    fread(buf,1,MAXB,stdin);
    n=read();
    int m=read();
    for(int i=1;i<=n;i++)
        a[i]=read();
    T.build(rt[0],1,n);
    for(int i=1;i<=m;i++){
        int pre=read(),opt=read(),x=read();
        if(opt==1) {//操作1:在版本pre的基础上将第x个数修改为v 
            int v=read();
            T.ins(rt[i],rt[pre],1,n,x,v);
        }
        if(opt==2) {//操作2:访问版本pre中第x个数的值 
            printf("%d\n",T.query(rt[pre],1,n,x));
            rt[i]=rt[pre];
        }
    }
}
posted @ 2018-02-20 23:36  yyy2015c01  阅读(188)  评论(0编辑  收藏  举报

在寒风中颤抖之时、听到了歌声—— 在傍晚的校园里,在无人在的食堂里,在孤寂的校舍窗边。
三年前被冰封的那首歌曲。 被热情突然迫动,点缀着纯粹的思念,欺瞒的歌曲逐渐溶化在夜里。
那时,三人一起的冬天已经远去, 一个人和另一个人的季节却在循环往复。 后续,就在这样的晚秋。 那个时候似要撕裂的羁绊的丑陋伤痕尚未干却, 但是伴随着有什么将要改变的预感中,开始了。
寂寞的两首旋律,互相吸引而再伤害彼此, 因此,新的旋律被召集来了。
不久,新的冬天即将到来。 不能和那个人在一起、而另一个人也已不在的冬天。
“白色相簿”什么的,已经无所谓了。 因为已经不再有歌,值得去唱了。
传达不了的恋情,已经不需要了。 因为已经不再有人,值得去爱了。