题意:中文题
思路:单点更新,区间求和的线段树入门题
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 50000+5;
//线段树需要维护的信息
int sum[maxn*4];
#define lson i*2,l,m
#define rson i*2+1,m+1,r
//i结点收集子结点的统计结果
void PushUp(int i)
{
sum[i]=sum[i*2]+sum[i*2+1];
}
//递归建立线段树
void build(int i,int l,int r)
{
if (l==r)
{
scanf("%d",&sum[i]);
return;
}
int m = (l+r)/2;
build(lson);
build(rson);
PushUp(i); //收集子结点的结果
}
//在当前区间[l,r]内查询区间[ql,qr]间的目标值
//且能执行这个函数的前提是:[l,r]与[ql,qr]的交集非空
//本函数返回的结果也就是它们交集的目标值
int query(int ql,int qr,int i,int l,int r)
{
//目的区间包含当前区间
if (ql <=l && qr>=r)
return sum[i];
int m = (l+r)/2;
int ans = 0;
if (ql <= m)
ans+=query(ql,qr,lson);
if (m < qr)
ans+=query(ql,qr,rson);
return ans;
}
//如果本题是单点更新,可以在区间[l,r]内使得第id数的值+val
//如果本题是区间更新,可以updata的参数需要将id改为ql,qr
void update(int id,int val,int i,int l,int r)
{
if (l==r)
{
sum[i]+=val;
return;
}
int m = (l+r)/2;
if (id <= m)
update(id,val,lson);
else
update(id,val,rson);
PushUp(i); //时刻记得维护i结点统计信息的正确性
}
int main()
{
int T;
int cas = 1;
scanf("%d",&T);
while (T--)
{
printf("Case %d:\n",cas++);
int n; //结点总数
scanf("%d",&n);
build(1,1,n);
char str[20];
while (scanf("%s",str)!=EOF && str[0]!='E')
{
int u,v;
scanf("%d%d",&u,&v);
if (str[0]=='Q')
printf("%d\n",query(u,v,1,1,n));
else if (str[0]=='A')
update(u,v,1,1,n);
else
update(u,-v,1,1,n);
}
}
}