题目大意:
给出一个序列和四种操作:
(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 表示结束,这条命令在每组数据最后出现;
执行操作并对(3)进行答复。
思路:
树状数组、线段树的模板题。
代码:
#include<iostream> #include<stdio.h> using namespace std; #define datasize 50000 int c[datasize+1],n; int lowbit(int x) { return x&-x; } int sum(int end) //求取序列1至end的和。 { int s=0; while(end>0) { s+=c[end]; end-=lowbit(end); } return s; } void modify(int pos,int val) //在序列第pos位上加上val。 { while(pos<=n) { c[pos]+=val; pos+=lowbit(pos); } } int main() { int t; scanf("%d",&t); for(int i=1;i<=t;i++) { printf("Case %d:\n",i); memset(c,0,sizeof(c)); scanf("%d",&n); for(int j=1,t;j<=n;j++) { scanf("%d",&t); modify(j,t); //更新操作即是建树操作。 } char op[10]; while(scanf("%s",op)&&strcmp(op,"End")) { int a,b; scanf("%d%d",&a,&b); if(!strcmp(op,"Query")) printf("%d\n",sum(b)-sum(a-1)); //[a,b]的和即是[1,b]的和减去[1,a-1]的和。 else if(!strcmp(op,"Add")) modify(a,b); else if(!strcmp(op,"Sub")) modify(a,-b); else break; } } }