敌兵布阵,线段树,N个阵营,每个阵营会增加或者减少m个士兵,查询的时候要查询任意区间里的士兵数量
AC代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int a[50001]; struct node { int left,right,sum; } b[150005]; int Query(int left,int right,int i) { int mid; if(b[i].left==left&&b[i].right==right) { return b[i].sum; } mid=(b[i].left+b[i].right)/2; if(right<=mid) { return Query(left,right,2*i); } else if(left>mid) { return Query(left,right,2*i+1); } else { return Query(left,mid,2*i)+Query(mid+1,right,2*i+1); } } void Add(int j,int num,int i) { if(b[i].left==b[i].right) { b[i].sum+=num; return ; } else { b[i].sum+=num; if(j<=b[2*i].right) { Add(j,num,2*i); } else { Add(j,num,2*i+1); } } } void Build(int left,int right,int i){//建树 int mid; b[i].left=left; b[i].right=right; if(left==right){//先用数组存下该队的人 b[i].sum=a[left]; return ; } //cout<<"ok"<<endl; mid=(left+right)/2; Build(left,mid,2*i);//递归建立左子树 Build(mid+1,right,2*i+1);//递归建立右子树 b[i].sum=b[2*i].sum+b[2*i+1].sum;//记录该结点左右子树的值 } int main() { int T,n,k,j,num; char s[10]; scanf("%d",&T); k=0; while(T--) { scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%d",&a[i]); } printf("Case %d: ",++k); Build(1,n,1); while(1) { scanf("%s",s); if(!strcmp(s,"End")) { break; } scanf("%d%d",&j,&num); if(!strcmp(s,"Query")) { printf("%d ",Query(j,num,1)); } else if(!strcmp(s,"Add")) { Add(j,num,1); } else if(!strcmp(s,"Sub")) { Add(j,-num,1); } } } return 0; }