【模板】可持久化线段树

洛谷3919

支持如下操作:

  1. 在某个历史版本上修改某一个位置上的值

  2. 访问某个历史版本上的某一位置的值
 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
",query(root[i],1,n,read()));
37     }
38     return 0;
39 }
View Code
原文地址:https://www.cnblogs.com/DriverLao/p/8029706.html