题目链接: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; }