[模板] 主席树
本质上是多棵线段树,动态开点,每次修改到root的一条链节约空间
可持久化数组(维护叶子节点的主席树)
#include<iostream> #include<cstdio> using namespace std; inline int rd(){ int ret=0,f=1;char c; while(c=getchar(),!isdigit(c))f=c=='-'?-1:1; while(isdigit(c))ret=ret*10+c-'0',c=getchar(); return ret*f; } const int MAXN = 1000005; int n,m; int a[MAXN],rt[MAXN]; int nodenum,ch[MAXN*40][2],val[MAXN*40]; inline int newnode(){return ++nodenum;} void build(int &cur,int l,int r){ cur=newnode(); if(l==r){val[cur]=a[l];return;} int mid=(l+r)>>1; build(ch[cur][0],l,mid); build(ch[cur][1],mid+1,r); } void update(int &cur,int pre,int l,int r,int x,int w){ if(!cur)cur=newnode(); val[cur]=val[pre]; if(l==r){val[cur]=w;return;} int mid=(l+r)>>1; if(x<=mid) update(ch[cur][0],ch[pre][0],l,mid,x,w),ch[cur][1]=ch[pre][1]; else update(ch[cur][1],ch[pre][1],mid+1,r,x,w),ch[cur][0]=ch[pre][0]; } int query(int cur,int l,int r,int x){ if(l==r)return val[cur]; int mid=(l+r)>>1; if(x<=mid) return query(ch[cur][0],l,mid,x); return query(ch[cur][1],mid+1,r,x); } int main(){ n=rd();m=rd(); for(int i=1;i<=n;i++){ a[i]=rd(); } build(rt[0],1,n); int x,y,z,w; for(int i=1;i<=m;i++){ x=rd();y=rd();z=rd(); if(y==1){ w=rd(); update(rt[i],rt[x],1,n,z,w); }else{ printf("%d\n",query(rt[x],1,n,z)); rt[i]=rt[x]; } } return 0; }
本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247421.html