树状数组真的是巧妙,发明这个的人一定是个天才。看了别人的博客半天大概知道是什么意思了,不过没有理解透彻,以后再说吧,反正核心代码也不长先背过再说。
推荐这篇博客我觉得树状数组讲的挺好的,http://blog.youkuaiyun.com/int64ago/article/details/7429868
还有这道题要注意的,一个是数据量较大,最好不要用cin/cout,一个是输入输出时注意格式。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int tree[50005];
void add(int k, int num,int n) //维护数组的函数
{
while(k<=n)
{
tree[k]+=num;
k+=k&-k; //lowbit利用了编码的知识
}
}
int read(int k) //1~k的区间和
{
int sum =0;
while(k)
{
sum+=tree[k];
k-=k&-k;
}
return sum;
}
int main()
{
int t;
scanf("%d",&t);
for(int k=1; k<=t; k++)
{
memset(tree,0,sizeof(tree));
int n,a,x,y;
char in[6];
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a);
add(i,a,n);
}
printf("Case %d:\n",k);
while(scanf("%s",in) !=EOF)
{
if(in[0] =='E')
break;
else if(in[0] =='Q')
{
scanf("%d%d",&x,&y);
printf("%d\n",read(y) - read(x-1));
}
else if(in[0] =='A')
{
scanf("%d%d",&x,&y);
add(x,y,n);
}
else if(in[0] =='S')
{
scanf("%d%d",&x,&y);
add(x,-y,n);
}
}
}
return 0;
}