之前用树状数组过掉了,这次用线段树重写了一遍,和求区间最值的那代码基本一样。。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <stack>
#include <algorithm>
#define MAXN 200005
#define MOD 1000000007
#define INF -2139062144
#define ll long long
//ios::sync_with_stdio(false)
using namespace std;
const int MAXN_N = 1<< 19;
int sum[2*MAXN_N],mxn,N;
void Init()
{
mxn=1;
while(mxn<N) mxn*=2;
memset(sum,0,sizeof(sum));
}
void update(int k,int val)
{
k+=mxn-1;
sum[k]+=val;
while(k/2>0)
{
k=k/2;
sum[k]+=val;
}
}
int Query(int a,int b,int k,int l,int r)
{
if(r<a||b<l) return 0;
if(a<=l&&r<=b) return sum[k];
else
{
int v1=Query(a,b,2*k,l,(l+r)/2);
int v2=Query(a,b,2*k+1,(l+r)/2+1,r);
return v1+v2;
}
}
int main()
{
int T,kase=0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
Init();
for(int i=1; i<=N; ++i)
{
int t;
scanf("%d",&t);
update(i,t);
}
char str[10];
printf("Case %d:\n",++kase);
while(scanf("%s",str))
{
if(str[0]=='E') break;
int a,b;
scanf("%d%d",&a,&b);
if(str[0]=='Q')
printf("%d\n",Query(a,b,1,1,mxn));
else if(str[0]=='A')
update(a,b);
else update(a,-b);
}
}
return 0;
}