可持久化数组学习

可持久化数组的写法和主席树差不多,但是主席树的每一棵树所表示的区间都不一样,而可持久化数组的每一棵树的区间都是一样的,剩下的写法就都差不多了;

附上代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
const int N = 1e6+10;

inline int read(){
    int ref=0,x=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')x=-1;ch=getchar();}
    while(isdigit(ch)){ref=ref*10+ch-'0';ch=getchar();}
    return ref*x;
}

int n,m;
int rt[N],val[N],tot;
int a[N];
struct tree{
    int val,ls,rs;
}t[N<<4];

void build(int &x,int l,int r){
    x=++tot;
    if(l==r){
        t[x].val=a[l];
        return ;
    }
    build(t[x].ls,l,mid);
    build(t[x].rs,mid+1,r);
}

void updata(int &x,int last,int l,int r,int pos,int k){
    x=++tot;
    t[x]=t[last];
    if(l==r){
        t[x].val=k;
        return ;
    }
    if(pos<=mid) updata(t[x].ls,t[last].ls,l,mid,pos,k);
    else updata(t[x].rs,t[last].rs,mid+1,r,pos,k);
}

int query(int x,int l,int r,int pos){
    if(l==r) return t[x].val;
    if(pos<=mid) return query(t[x].ls,l,mid,pos);
    else return query(t[x].rs,mid+1,r,pos);
}

int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    build(rt[0],1,n);
    for(int i=1;i<=m;i++){
        int op,x,y,z;
        x=read(),op=read();
        if(op==1){
            y=read(),z=read();
            updata(rt[i],rt[x],1,n,y,z);
        }
        else {
            y=read();
            rt[i]=rt[x];
            int ans=query(rt[x],1,n,y);
            printf("%d\n",ans);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/nnezgy/p/11403558.html