#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
#define Size 50000
struct node
{
int L, R, V;
node* lchild;
node* rchild;
}Tree[2*Size];// 线段树 用到指针 所以整个线段树 所占空间为 2倍叶子节点-1
int Mid( node* root )
{
return (root->L + root->R)/2;
}
int nCount;
void BuildTree( node* root, int L, int R )// 初始化区间为[L,R]的线段树
{
root -> L = L;
root -> R = R;
root -> V = 0;
if( L == R )
return ;
nCount++;
root -> lchild = Tree + nCount;
nCount++;
root -> rchild = Tree + nCount;
BuildTree( root->lchild, L, (L+R)/2 );
BuildTree( root->rchild, (L+R)/2+1, R );
}
void Insert( node* root, int i, int v ) 在单位区间 i 上 插入 值为v的数
{
if( root->L == i && root->R == i )
{
root->V = v;
return ;
}
root -> V += v;// 更新 所在路径上区间的值
if( i <= Mid( root ) )
Insert( root->lchild, i, v );
else
Insert( root->rchild, i, v );
}
void Add( node* root, int i, int j )// 在 i上 加上 j
{
if( root->L == i && root->R == i )
{
root->V += j;
return ;
}
root->V += j;
if( i<=Mid( root ) )
Add( root->lchild, i, j );
else
Add( root->rchild, i, j );
}
int Query( node* root, int s, int e )// 区间 [s,e] 求和
{
if( root->L==s && root->R == e )
return root->V;
if( e<=Mid(root) )
return Query( root->lchild, s, e );
else if( s>=Mid(root)+1 )
return Query( root->rchild, s, e );
else
return Query( root->lchild, s, Mid(root) )
+Query( root->rchild, Mid(root)+1, e );
}
int main()
{
int T, N;
cin>>T;
for( int i=1; i<=T; i++ )
{
printf( "Case %d:\n", i );
nCount = 0;
scanf( "%d", &N );
BuildTree( Tree, 1, N );
int Val;
for( int j=1; j<=N; j++ )
{
scanf("%d", &Val);
Insert( Tree, j, Val );
}
string cmd;
int a, b;
while(cin>>cmd && cmd!="End"){
if( cmd == "Query" )
{
scanf( "%d %d", &a, &b );
cout<<Query( Tree, a, b )<<endl;
}
else if( cmd == "Add" )
{
scanf( "%d %d", &a, &b );
Add( Tree, a, b );
}
else if( cmd == "Sub" )
{
scanf( "%d %d", &a, &b );
Add( Tree, a, -b );
}
}
}
return 0;
}