http://acm.hdu.edu.cn/showproblem.php?pid=1166
直接线段树模板
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int l; //左起点
int r; //右终点
int sum; //区间数据总和
};
node p[200004];
int a[50001];
int n;
void biuld(int k, int l, int r) //创建
{
int mid;
p[k].l = l;
p[k].r = r;
if(l == r)
{
p[k].sum = a[l];
return ;
}
mid = (l+r)/2;
biuld(k*2,l,mid);
biuld(k*2+1,mid+1,r);
p[k].sum = p[k*2].sum+p[k*2+1].sum;
return ;
}
int find(int k, int l, int r) //查找区间的值
{
int mid;
if(p[k].l==l && p[k].r==r) //找到这个区间
{
return p[k].sum;
}
mid = (p[k].l+p[k].r)/2;
if(l>mid) //在中点的右孩子
{
return find(k*2+1,l,r);
}
if(r<=mid) //在中点得左孩子
{
return find(k*2,l,r);
}
return find(k*2,l,mid) + find(k*2+1,mid+1,r);
}
void update(int k, int x, int y) //更新数据
{
int mid;
if(p[k].l==x && p[k].r==x) //如果找到这个点
{
p[k].sum = y; //更新数据
return ;
}
mid = (p[k].l+p[k].r)/2;
if(x<=mid)
{
update(k*2,x,y);
}
else
{
update(k*2+1,x,y);
}
p[k].sum=p[k*2].sum+p[k*2+1].sum;
return ;
}
int main()
{
int t,i,k,x,y,m;
char cz[7];
scanf("%d",&t);
k = 0;
while(t--)
{
k++;
scanf("%d",&n);
for(i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
}
biuld(1,1,n);
printf("Case %d:\n",k);
while(1)
{
scanf("%s",&cz);
if(cz[0]=='E')
{
break;
}
scanf("%d%d",&x,&y);
switch(cz[0])
{
case 'Q':
{
printf("%d\n",find(1,x,y));
break;
}
case 'A':
{
a[x]+=y;
m = a[x];
update(1,x,m);
break;
}
case 'S':
{
a[x]-=y;
m = a[x];
update(1,x,m);
}
}
}
}
return 0;
}