线段树单点更新,裸过题:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 50005;
int s[N << 2], lc[N << 2], rc[N << 2];
int num[N], n, m;
void build(int u ,int l ,int r) {
lc[u] = l;
rc[u] = r;
if(l == r) {
s[u] = num[l];
return;
}
int mid = (l + r) / 2;
build(u * 2 , l , mid);
build(u * 2 + 1 , mid + 1 ,r);
s[u] = s[u * 2] + s[u * 2 + 1];
}
void mofiy(int u , int x ,int v) {
if(lc[u] == x && rc[u] == x) {
s[u] += v;
return ;
}
int mid = (lc[u] + rc[u]) / 2;
if(x <= mid)
mofiy(u * 2 , x , v);
else
mofiy(u * 2 + 1 , x, v);
s[u] = s[u * 2] + s[u * 2 + 1];
}
void mofiy2(int u , int x ,int v) {
if(lc[u] == x && rc[u] == x) {
s[u] -= v;
return ;
}
int mid = (lc[u] + rc[u]) / 2;
if(x <= mid)
mofiy2(u * 2 , x , v);
else
mofiy2(u * 2 + 1 , x, v);
s[u] = s[u * 2] + s[u * 2 + 1];
}
int query(int u , int l ,int r) {
int ret = 0;
if(l <= lc[u] && r >= rc[u])
return s[u];
int mid = (lc[u] + rc[u]) / 2;
if(l <= mid) {
int temp = query(u * 2 , l ,r);
ret += temp;
}
if(r > mid) {
int temp = query(u * 2 + 1, l , r);
ret += temp;
}
return ret;
}
int main (){
int t ;
int cas = 1;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i = 1 ; i <= n ; i++) {
scanf("%d",&num[i]);
}
build(1 , 1 , n);
printf("Case %d:\n",cas++);
char str[10];
while(1) {
scanf("%s",str);
if(str[0] == 'E')
break;
if(str[0] == 'A') {
int a,b;
scanf("%d%d",&a,&b);
mofiy(1 , a , b);
}
if(str[0] == 'S') {
int a,b;
scanf("%d%d",&a,&b);
mofiy2(1 , a , b);
}
if(str[0] == 'Q'){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",query(1 , a, b)) ;
}
}
}
}