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