Description
Input
Output
Sample Input
1 10 1 2 3 4 5 6 7 8 9 10 Query 1 3 Add 3 6 Query 2 7 Sub 10 2 Add 6 3 Query 3 10 End
Sample Output
Case 1: 6 33 59
#include
struct stu
{
int l,r,num; //l,r表示叶子代表的区间左右边界
}ye[200000]; //ye[k]代表第k个叶子(k并不与军营数对应)
void init_tree(int l,int r,int k) //建树函数 l,r分别代表每个叶子的左右边界 k为每个叶子的编号
{
ye[k].l=l;
ye[k].r=r;
ye[k].num=0;
if(r == l)
return;
int mid = (l + r)/2;
init_tree(l,mid,k*2);
init_tree(mid+1,r,k*2+1);
}
void updata_tree(int i,int add,int k) //更新叶子的值 i代表军营编号 add表示增加的人数 k同上
{
if(ye[k].l == i && ye[k].r == i) //终止条件 找到表示单个军营的叶子(叶子可表示区间,也可表示单个点)
{
ye[k].num+=add;
return;
}
int mid = (ye[k].l + ye[k].r)/2;
if(mid >= i)
{
updata_tree(i,add,k*2);
}
else
{
updata_tree(i,add,k*2+1);
}
ye[k].num=ye[k*2].num+ye[k*2+1].num;
}
int sum;
void search_tree(int l,int r,int k) //搜索叶子的值 l,r表示要找的军营区间 k同上
{
if(ye[k].l == l && ye[k].r == r) //终止条件 表示找到表示区间l,r的叶子 (l,r不一定是要求的军营区间,可能是函数套用)
{
sum+=ye[k].num;
return;
}
int mid=(ye[k].l + ye[k].r)/2; //三种情况
if(mid >= r)
{
search_tree(l,r,k*2);
}
else if(mid < l)
{
search_tree(l,r,k*2+1);
}
else
{
search_tree(l,mid,k*2);
search_tree(mid+1,r,k*2+1);
}
}
int main()
{
int t,ss=0,i,a;
char st[20];
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
init_tree(1,n,1);
for(i = 1 ; i <= n ; i++)
{
scanf("%d",&a);
updata_tree(i,a,1);
}
printf("Case %d:\n",++ss);
while(scanf("%s",&st) && st[0] != 'E')
{
sum=0;
int a,b;
if(st[0] == 'A')
{
scanf("%d %d",&a,&b);
updata_tree(a,b,1);
}
else if(st[0] == 'S')
{
scanf("%d %d",&a,&b);
updata_tree(a,-b,1);
}
else
{
scanf("%d %d",&a,&b);
search_tree(a,b,1);
printf("%d\n",sum);
}
}
}
}