本题是线段树的基本模板题,包含以下几部分:
1、修改值
2、查询区间和
AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; int sum[maxn*4],add[maxn*4]; int a[maxn]; void pushup(int root) //根节点的和=两个子节点的和 { sum[root]=(sum[root*2]+sum[root*2+1]); } void build(int l,int r,int root)//建树 { if(l==r) { sum[root] = a[l]; return; } int mid=(l+r)/2; build(l,mid,root*2); build(mid+1,r,root*2+1); pushup(root); } void Add(int num,int val,int l,int r,int root)//修改值 { if(l==r&&num==l) { a[num]+=val; sum[root]=a[num]; return; } int mid=(l+r)/2; if(num<=mid) Add(num,val,l,mid,root*2); else Add(num,val,mid+1,r,root*2+1); pushup(root); } int Query(int be,int ed,int l,int r,int root)//查询区间和 { if(be<=l&&r<=ed) return sum[root]; int mid=(l+r)/2; int ans=0; if(be<=mid) ans+=Query(be,ed,l,mid,root*2); if(mid<ed) ans+=Query(be,ed,mid+1,r,root*2+1); return ans; } int main() { int T; scanf("%d",&T); int res=1; while(T--) { int n; scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d",&a[i]); } build(1,n,1); char s[10]; int a,b; printf("Case %d: ",res); while(scanf("%s",s)) { if(s[0]=='E') break; if(s[0]=='A') { scanf("%d %d",&a,&b); Add(a,b,1,n,1); } if(s[0]=='Q') { scanf("%d %d",&a,&b); printf("%d ",Query(a,b,1,n,1)); } if(s[0]=='S') //减去某个值可以认为是加上某值的相反数 { scanf("%d %d",&a,&b); Add(a,-b,1,n,1); } } res++; } return 0; }