题目大意:N个阵地的士兵个数是可能发生变化的,根据输入给出的操作,求出所查询的区间内的士兵总数
输入:
case个数T
阵地个数N
第i个阵地的人数a[i]
指令(四种:Add x y表示x阵地加y个人
Sub x y表示x阵地减y个人
Query x y表示查询x到y阵地的总人数
End表示结束case)
输出:区间内士兵总数
分析:树状数组。线段树也能做,但是这道题用树状数组比较简单快速。线段树比较适合记录区间内的特征值,例如最值等等。
代码:
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int N;
int a[50001];
int c[50001];
char command[10];
int x, y;
void update(int i, int val){
while (i <= N){
c[i] += val;
i += i&(-i);
}
}
int sum(int i){
int total = 0;
while (i > 0){
total += c[i];
i -= i&(-i);
}
return total;
}
int main(){
int T,cases = 1;
scanf("%d", &T);
while (T--){
scanf("%d", &N);
memset(c, 0, sizeof(c));
for (int i = 1; i <= N; i++){
scanf("%d", &a[i]);
update(i, a[i]);
}
printf("Case %d:\n", cases++);
while (scanf("%s", command)){
if (command[0] == 'E')
break;
scanf("%d %d", &x, &y);
if (command[0] == 'Q'){
printf("%d\n", sum(y) - sum(x - 1));
}
else if (command[0] == 'A'){
update(x, y);
}
else if (command[0] == 'S'){
update(x, -y);
}
}
}
return 0;
}