题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
题目大意:
有n个区间,端点更新,查询一段空间内的士兵总和。
解题思路:
线段树的端点更新。
代码:
//端点更新 #include<iostream> using namespace std; #define lson l,m,rt<<1 //建树,查询,更新都会用到 #define rson m+1,r,rt<<1|1 #define maxn 55000 int sum[maxn*4]; void PushUp(int temp) //向上更新 { sum[temp]=sum[temp<<1]+sum[temp<<1|1]; return ; } void Build(int l,int r,int rt) { if(l==r) //到达了叶子节点,这时可以读入数据 { scanf("%d",&sum[rt]); return ; } int m=(l+r)>>1; Build(lson); //建左孩子 Build(rson); //建右孩子 PushUp(rt); //向上更新 return ; } int Query(int L,int R,int l,int r,int rt) { if(l>=L&&r<=R) //当前区间在所查区间内,直接返回该区间的值 return sum[rt]; int temp=0,m=(l+r)>>1; //如果当前区间不在所查区间内 if(L<=m) //一定要查左边的 temp+=Query(L,R,lson); if(R>m) //一定要查右边 temp+=Query(L,R,rson); return temp; } void Add(int temp,int tar,int l,int r,int rt) { if(l==r) //找到了 { sum[rt]+=tar; return; } int m=(l+r)>>1; //当前区间分成两部分来查找 if(temp<=m) Add(temp,tar,lson); else Add(temp,tar,rson); PushUp(rt); //更新叶子节点后,注意向上更新 return ; } int main() { int ca,n; char order[25]; scanf("%d",&ca); for(int cnt=1;cnt<=ca;cnt++) { int a,b; printf("Case %d:\n",cnt); scanf("%d",&n); Build(1,n,1); while(scanf("%s",order)!=EOF) { if(*order=='E') break; scanf("%d%d",&a,&b); if(*order=='Q') printf("%d\n",Query(a,b,1,n,1)); else if(*order=='A') Add(a,b,1,n,1); else Add(a,-b,1,n,1); } } return 0; }