Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
1.此题可以用树状数组来做,其操作为给某一个兵营增加或者减少人数,以及询问i 到 j总人数,可以用树状数组维护前i个营地的人数总数,通过前j个营地的人数总数减去前i-1个营地的总人数就得到i到j的营地总人数。
2.sum() ------k减少 (因为一直在取最后面一个1,得到c[k]后减去,一直重复,k的1总有取尽的时候,也就是到0)
add()--------k增加 (因为k以上的父节点,每个都要增加V)
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define nmax 50004
int c[50004];
int n;
int lowbit(int k)
{
return k&(-k);
}
void add(int k,int v)
{
while(k<=n)
{
c[k]=c[k]+v;
k=k+lowbit(k);
}
}
int sum(int k)
{
int cnt=0;
while(k>0)
{
cnt=cnt+c[k];
k=k-lowbit(k);
}
return cnt;
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=t;i++)
{
memset(c,0,sizeof(c));
printf("Case %d:\n",i);
char query[20];
int a,b;
scanf("%d",&n);
for(int j=1;j<=n;j++)
{
int num;
scanf("%d",&num);
add(j,num);
}
while(scanf("%s",query)!=EOF)
{
if(query[0]=='E') break;
scanf("%d%d",&a,&b);
if(query[0]=='A')
{
add(a,b);
}
if(query[0]=='S')
{
add(a,-b);
}
if(query[0]=='Q')
{
printf("%d\n",sum(b)-sum(a-1));
}
}
}
return 0;
}