这道题算是线段树的入门题了,线段树理解的话其实是挺好理解的,但写的话就感觉挺不好写的,毕竟有好几十行代码,讲解的话看下别人的博客,他们讲的我觉得很清楚了,然后如果觉得我的代码风格跟你差不多的,能接受我的这种写法的话,有什么不懂得可以问我。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define lson l, mid, o << 1
#define rson mid + 1, r, o << 1 | 1
#define maxn 50005
using namespace std;
int sum[maxn << 2];
int T,n;
string str;
void Pushup(int o){
sum[o] = sum[o << 1] + sum[o << 1 | 1]; // 向上更新维护一个sum值
}
void Build(int l, int r, int o){
if(l == r){
scanf("%d",&sum[o]);
return ;
}
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
Pushup(o);
}
void Update(int x, int ans, int l, int r,int o){
if(l == r){
sum[o] += ans;
return ;
}
int mid = (l + r) >> 1;
if(x <= mid) Update(x, ans, lson);
else Update(x, ans, rson);
Pushup(o);
}
int Query(int L, int R, int l, int r, int o){
if(L <= l && r <= R){
return sum[o];
}
int mid = (l + r) >> 1;
int ans = 0;
if(L <= mid) ans += Query(L, R, lson);
if(R > mid) ans += Query(L, R, rson);
return ans;
}
int main()
{
int Case = 1;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
Build(1,n,1);
int a,b;
printf("Case %d:\n",Case++);
while(cin>>str){
if(str == "End")break;
scanf("%d%d",&a,&b);
if(str == "Add"){
Update(a,b,1,n,1);
}
else if(str == "Sub"){
Update(a,-b,1,n,1);
}
else{
printf("%d\n",Query(a,b,1,n,1));
}
}
}
return 0;
}