输入:
5 10
59 46 14 87 41
0 2 1
0 1 1 14
0 1 1 57
0 1 1 88
4 2 4
0 2 5
0 2 4
4 2 1
2 2 2
1 1 5 91
输出:
59
87
41
87
88
46
分析:
这个题目的每个询问都会生成一个版本,所以说就是主席树的裸模板啦,最简单的主席树模板了,分享一下子我的模板吧,感觉还挺不错的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 1000010;
typedef long long LL;
struct node
{
int l,r;
LL sum;
};
node tr[N*25];
int idx,root[N];
int build(int l,int r){
int q = ++idx;
tr[q] = {0,0,0};
if(l == r){
scanf("%lld",&tr[q].sum);
return q;
}
int mid = l + r >> 1;
tr[q].l = build(l,mid);
tr[q].r = build(mid+1,r);
tr[q].sum = tr[tr[q].l].sum + tr[tr[q].r].sum;
return q;
}
int update(int p,int l,int r,int pos,int val){
int q = ++idx;
tr[q] = tr[p];
if(l == r){
tr[q].sum = val;
return q;
}
int mid = l + r >> 1;
if(pos <= mid) tr[q].l = update(tr[p].l,l,mid,pos,val);
else tr[q].r = update(tr[p].r,mid+1,r,pos,val);
tr[q].sum = tr[tr[q].l].sum + tr[tr[q].r].sum;
return q;
}
LL query(int p,int l,int r,int L,int R){
if(l >= L && r <= R) return tr[p].sum;
int mid = l + r >> 1;
int ans = 0;
if(mid >= L) ans += query(tr[p].l,l,mid,L,R);
if(mid < R) ans += query(tr[p].r,mid+1,r,L,R);
return ans;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
root[0] = build(1,n);
for(int i=1;i<=m;i++){
int op,v;
scanf("%d%d",&v,&op);
if(op == 1){
int pos,val;
scanf("%d%d",&pos,&val);
root[i] = update(root[v],1,n,pos,val);
}
else{
int pos;
scanf("%d",&pos);
printf("%lld\n",query(root[v],1,n,pos,pos));
root[i] = root[v];
}
}
return 0;
}