//HDU1166-线段树模板(区间和):曾贵胜
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define N 50005
using namespace std;
int num[N];
struct Tree
{
int l; //左端点
int r; //右端点
int sum; //总数
}tree[N*4]; //总线段长度为N,若开数组,一般开到N的4倍
void build(int root,int l,int r) //建立线段树:root为根节点,它的区间为[l,r]
{
tree[root].l=l;
tree[root].r=r;
if(tree[root].l==tree[root].r) //当左右端点相等时就是叶子节点
{
tree[root].sum=num[l]; //赋初值
return; //递归出口
}
int mid=(l+r)/2;
build(root<<1,l,mid); //root<<1 相当于root*2 ,即它的左孩子
build(root<<1|1,mid+1,r); //root<<1|1 相当于root*2+1 ,即它的右孩子
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; //父亲的sum=左孩子的sum+右孩子的sum
}
void update(int root,int pos,int val) //更新:root是根节点,pos和val表示将在pos点的值更新为val
{
if(tree[root].l==tree[root].r) //如果是叶子节点,即是pos对应的位置
{
tree[root].sum=val; //更新操作
return; //递归出口
}
int mid=(tree[root].l+tree[root].r)/2;
if(pos<=mid) //如果pos点是root对应的左孩子
update(root<<1,pos,val); //在左孩子里面找
else
update(root<<1|1,pos,val); //在右孩子里面找
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; //父亲的sum=左孩子的sum+右孩子的sum
}
int query(int root,int L,int R) //查询:root为根节点,[L,R]表示要查询的区间
{
if(L<=tree[root].l && R>=tree[root].r) //如果要查询的区间[L,R]包含root节点表示的区间
return tree[root].sum; //直接返回root节点的sum值
int mid=(tree[root].l+tree[root].r)/2;
int ret=0;
if(L<=mid) ret+=query(root<<1,L,R); //查询root节点的左孩子
if(R>mid) ret+=query(root<<1|1,L,R); //查询root节点的右孩子
return ret; //返回查询结果
}
int main()
{
//freopen("hdu1166.in","r",stdin);
//freopen("hdu1166.out","w",stdout);
int T,n,a,b;
char str[10];
scanf("%d", &T); //数据组数
for(int cas=1;cas<=T;cas++)
{
scanf("%d", &n);
for(int i=1;i<=n;i++)
scanf("%d", &num[i]); //在i点的兵力数量
build(1,1,n); //从根节点1开始构建线段树,区间[1,n]
printf("Case %d:\n",cas);
while(scanf("%s",str),strcmp(str,"End"))
{
scanf("%d%d",&a,&b);
if(strcmp(str,"Query")==0) //也可写成 if(str[0]=='Q')
{
if(a>b) swap(a,b); //查询区间[a,b]
printf("%d\n",query(1,a,b)); //输出查询结果
}
if(strcmp(str,"Add")==0) //也可写成 if(str[0]=='A')
{
num[a]=num[a]+b; //增加
update(1,a,num[a]); //更新a点的值为num[a]
}
if(strcmp(str,"Sub")==0) //也可写成 if(str[0]=='S')
{
num[a]=num[a]-b; //减少
update(1,a,num[a]); //更新a点的值为num[a]
}
}
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define N 50005
using namespace std;
int num[N];
struct Tree
{
int l; //左端点
int r; //右端点
int sum; //总数
}tree[N*4]; //总线段长度为N,若开数组,一般开到N的4倍
void build(int root,int l,int r) //建立线段树:root为根节点,它的区间为[l,r]
{
tree[root].l=l;
tree[root].r=r;
if(tree[root].l==tree[root].r) //当左右端点相等时就是叶子节点
{
tree[root].sum=num[l]; //赋初值
return; //递归出口
}
int mid=(l+r)/2;
build(root<<1,l,mid); //root<<1 相当于root*2 ,即它的左孩子
build(root<<1|1,mid+1,r); //root<<1|1 相当于root*2+1 ,即它的右孩子
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; //父亲的sum=左孩子的sum+右孩子的sum
}
void update(int root,int pos,int val) //更新:root是根节点,pos和val表示将在pos点的值更新为val
{
if(tree[root].l==tree[root].r) //如果是叶子节点,即是pos对应的位置
{
tree[root].sum=val; //更新操作
return; //递归出口
}
int mid=(tree[root].l+tree[root].r)/2;
if(pos<=mid) //如果pos点是root对应的左孩子
update(root<<1,pos,val); //在左孩子里面找
else
update(root<<1|1,pos,val); //在右孩子里面找
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; //父亲的sum=左孩子的sum+右孩子的sum
}
int query(int root,int L,int R) //查询:root为根节点,[L,R]表示要查询的区间
{
if(L<=tree[root].l && R>=tree[root].r) //如果要查询的区间[L,R]包含root节点表示的区间
return tree[root].sum; //直接返回root节点的sum值
int mid=(tree[root].l+tree[root].r)/2;
int ret=0;
if(L<=mid) ret+=query(root<<1,L,R); //查询root节点的左孩子
if(R>mid) ret+=query(root<<1|1,L,R); //查询root节点的右孩子
return ret; //返回查询结果
}
int main()
{
//freopen("hdu1166.in","r",stdin);
//freopen("hdu1166.out","w",stdout);
int T,n,a,b;
char str[10];
scanf("%d", &T); //数据组数
for(int cas=1;cas<=T;cas++)
{
scanf("%d", &n);
for(int i=1;i<=n;i++)
scanf("%d", &num[i]); //在i点的兵力数量
build(1,1,n); //从根节点1开始构建线段树,区间[1,n]
printf("Case %d:\n",cas);
while(scanf("%s",str),strcmp(str,"End"))
{
scanf("%d%d",&a,&b);
if(strcmp(str,"Query")==0) //也可写成 if(str[0]=='Q')
{
if(a>b) swap(a,b); //查询区间[a,b]
printf("%d\n",query(1,a,b)); //输出查询结果
}
if(strcmp(str,"Add")==0) //也可写成 if(str[0]=='A')
{
num[a]=num[a]+b; //增加
update(1,a,num[a]); //更新a点的值为num[a]
}
if(strcmp(str,"Sub")==0) //也可写成 if(str[0]=='S')
{
num[a]=num[a]-b; //减少
update(1,a,num[a]); //更新a点的值为num[a]
}
}
}
return 0;
}