题目描述:
食堂有N个打饭窗口,现在正到了午饭时间,每个窗口都排了很多的学生,而且每个窗口排队的人数在不断的变化。
现在问你第i个窗口到第j个窗口一共有多少人在排队?
输入:
输入的第一行是一个整数T,表示有T组测试数据。
每组输入的第一行是一个正整数N(N<=30000),表示食堂有N个窗口。
接下来一行输入N个正整数,第i个正整数ai表示第i个窗口最开始有ai个人排队。(1<=ai<=50)
接下来每行有一条命令,命令有四种形式:
(1)Add i j,i和j为正整数,表示第i个窗口增加j个人(j不超过30);
(2)Sub i j,i和j为正整数,表示第i个窗口减少j个人(j不超过30);
(3)Query i j,i和j为正整数,i<=j,表示询问第i到第j个窗口的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;
每组数据最多有40000条命令。
输出:
对于每组输入,首先输出样例号,占一行。
然后对于每个Query询问,输出一个整数,占一行,表示询问的段中的总人数,这个数保持在int以内。
样例输入:
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
样例输出:
Case 1:
6
33
59
题解:
本题作为区间查询的练习题,实际上题目已经做好了分化区间,即分窗口统计人数,只需要在此基础上做各窗口人数的统计即可。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=3*1e4+10;
void act(string str,int a[]){
if(str=="End") return;
int i,j,sum=0;
scanf("%d%d",&i,&j);
if(str=="Add") a[i]+=j;
if(str=="Sub") a[i]-=j;
if(str=="Query"){
for(;i<=j;++i){
// cout<<a[i]<<endl;
sum+=a[i];
}
printf("%d\n",sum);
}
return;
}
int main(){
int i;
int T; // T组数据
int N; // N个窗口
int a[MAXN]; // 每个窗口人数数组
string str; // 每次输入的指令
scanf("%d",&T);
int n=0;// 样例号
while(T--){
printf("Case %d:\n",++n);
memset(a,0,sizeof(a));
scanf("%d",&N);
for(i=1;i<=N;++i){
scanf("%d",a+i);
}
do{
cin>>str;
act(str,a);
}while(str!="End");
}
return 0;
}