#include<stdio.h>
#include<math.h>
#include<string.h>
#define maxn 50005
struct node
{
int L, R, sum;//左右子树,sum记录区间和
int Mid(){return (L+R)/2;}
}tree[maxn*4];//为了保险起见一般定义是四倍
int val[maxn];//保存每个阵地原来的人数
void Build(int root, int L, int R)//建树
{
tree[root].L = L, tree[root].R = R;
if(L == R)
{
tree[root].sum = val[L];
return ;
}
Build(root<<1, L, tree[root].Mid());//<<1 运算符相当于乘上 2,因为是数往左移一位
Build(root<<1|1, tree[root].Mid()+1, R);//|1, 因为左移后最后一位是0, 所以与1进行|相当于+1
tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;//区间和等于左右区间的和
}
//k表示需要更新的点,e表示需要更新的值
void Insert(int root, int k, int e)
{
tree[root].sum += e;
if(tree[root].L == tree[root].R)
return ;
if(k <= tree[root].Mid())
Insert(root<<1, k, e);
else
Insert(root<<1|1, k, e);
}
//查询区间LR的和
int Query(int root, int L, int R)
{
if(tree[root].L == L && tree[root].R == R)
return tree[root].sum;
//如果在左子树区间
if(R <= tree[root].Mid())
return Query(root<<1, L, R);
else if(L > tree[root].Mid())//如果在右子树区间
return Query(root<<1|1, L, R);
else
{//在左右子树
int Lsum = Query(root<<1, L, tree[root].Mid());
int Rsum = Query(root<<1|1, tree[root].Mid()+1, R);
return Lsum + Rsum;
}
}
int main()
{
int T, t=1;
scanf("%d", &T);
while(T--)
{
int i, N, x, y;
scanf("%d", &N);
for(i=1; i<=N; i++)
scanf("%d", &val[i]);
Build(1, 1, N);
char s[10];
printf("Case %d:\n", t++);
while(scanf("%s", s), s[0] != ‘E‘)
{
scanf("%d%d", &x, &y);
if(s[0] == ‘A‘)
Insert(1, x, y);
else if(s[0] == ‘S‘)
Insert(1, x, -y);
else
{
int ans = Query(1, x, y);
printf("%d\n", ans);
}
}
}
return 0;
}