问题概述:先输入一个数n,接下来输入n个数,然后输入一个指令,其中(Add i j)i和j为正整数,表示第i个营地增加j个人,(Sub i j)i和j为正整数,表示第i个营地减少j个人,(Query i j)i和j为正整数,i<=j,表示询问第i到第j个营地的总人数,(End)表示结束,这条命令在每组数据最后出现,对于每个Query询问,输出该区间中的总人数(T组实例)
输入样例: 对应输出:
1 Case 1:
10 6
1 2 3 4 5 6 7 8 9 10 3
Query 1 3 59
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
大神:http://blog.csdn.net/int64ago/article/details/7429868
解析在代码中
#include<stdio.h>
#include<string.h>
int n;
int c[50005];
void Update(int x, int k);
int Print(int k);
int lowbit(int k)
{
return k&-k; /*把k的二进制的高位1全部清空,只留下最低位的1*/
}
int main(void)
{
int T, cas, i, a, b;
char str[12];
scanf("%d", &T);
cas = 1;
while(T--)
{
memset(c, 0, sizeof(c)); /*将数组的所有元素全部重置为0*/
scanf("%d", &n);
for(i=1;i<=n;i++)
{
scanf("%d", &a);
Update(a, i); /*每输入一个数,更新一次树状数组*/
}
printf("Case %d:\n", cas++);
while(scanf("%s", str), strcmp(str, "End")!=0)
{
scanf("%d%d", &a, &b);
if(str[0]=='A')
Update(b, a);
if(str[0]=='S')
Update(-b, a);
if(str[0]=='Q')
printf("%d\n", Print(b)-Print(a-1));
}
}
return 0;
}
void Update(int x, int k) /*树状数组的更新*/
{
while(k<=n)
{
c[k] += x;
k += lowbit(k);
}
}
int Print(int k) /*查询1-k的区间和*/
{
int ans;
ans = 0;
while(k>0)
{
ans += c[k];
k -= lowbit(k);
}
return ans;
}