题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
最基础的线段树问题。
单点更新,区间查找。
本题可以用树状数组做,但是线段树除了处理区间求和问题外,还可以处理区间极值问题,所以虽然ZKW树状数组可以取代线段树的求和部分,但是并不能却带线段树在其他领域的功用。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
#define Maxn 50005
#define lx (x<<1)
#define rx (x<<1 | 1)
#define MID ((l + r)>>1)
int A[Maxn];
int S[Maxn<<2];
void pushUp(int x)
{
S[x] = S[lx] + S[rx];
}
void build(int l,int r,int x)
{
if(l == r)
{
S[x] = A[l];
return;
}
build(l,MID,lx);
build(MID+1,r,rx);
pushUp(x);
}
int query(int L,int R,int l,int r,int x)
{
if(L<=l && r<=R) return S[x];
int ans = 0;
if(L<=MID) ans += query(L,R,l,MID,lx);
if(MID<R) ans += query(L,R,MID+1,r,rx);
return ans;
}
void update(int p,int d,int l,int r,int x)
{
if(l == r)
{
S[x] += d;
return;
}
if(p <= MID) update(p,d,l,MID,lx);
else update(p,d,MID+1,r,rx);
pushUp(x);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t;
int n;
char cmd[10];
int cas = 0;
int a,b;
scanf(" %d",&t);
while(t--)
{
cas++;
printf("Case %d:\n",cas);
scanf(" %d",&n);
for(int i=1;i<=n;i++) scanf(" %d",&A[i]);
build(1,n,1);
while(scanf(" %s",cmd)!=EOF && cmd[0]!='E')
{
scanf(" %d %d",&a,&b);
if(cmd[0] == 'Q') printf("%d\n",query(a,b,1,n,1));
else if(cmd[0] == 'S') update(a,-b,1,n,1);
else if(cmd[0] == 'A') update(a,b,1,n,1);
}
}
return 0;
}