【模板】可持久化线段树
洛谷3919
支持如下操作:
-
在某个历史版本上修改某一个位置上的值
- 访问某个历史版本上的某一位置的值
1 #include<cstdio> 2 #include<algorithm> 3 #define ls(x) (a[x].ls) 4 #define rs(x) (a[x].rs) 5 #define mid ((l+r)>>1) 6 using namespace std; 7 int n,m,tot,root[1000010]; 8 struct tree{int ls,rs,del;}a[40000010]; 9 inline int read(){ 10 int k=0,f=1; char c=getchar(); 11 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 12 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 13 return k*=f; 14 } 15 void build(int &u,int l,int r){ 16 u=++tot; 17 if(l==r) a[u].del=read(); 18 else build(ls(u),l,mid),build(rs(u),mid+1,r); 19 } 20 void change(int u,int l,int r,int del,int pos){ 21 if(l==r) a[u].del=del; 22 else{ 23 if(pos<=mid) a[++tot]=a[ls(u)],ls(u)=tot,change(tot,l,mid,del,pos); 24 else a[++tot]=a[rs(u)],rs(u)=tot,change(tot,mid+1,r,del,pos); 25 } 26 } 27 int query(int u,int l,int r,int pos){ 28 if(l==r) return a[u].del; 29 else return pos<=mid?query(ls(u),l,mid,pos):query(rs(u),mid+1,r,pos); 30 } 31 int main(){ 32 n=read(); m=read(); build(root[0],1,n); 33 for(int i=1;i<=m;i++){ 34 a[root[i]=++tot]=a[root[read()]]; 35 if(read()==1) change(root[i],1,n,read(),read()); 36 else printf("%d\n",query(root[i],1,n,read())); 37 } 38 return 0; 39 }