题意
n个阵营一字排开,每个初始有a[i]个人。现有两种操作:
Q a b 查询[a,b]之间总人数并输出
A/S a b 在a号位添加/删除b个人
线段树功能:update:单点增减 query:区间求和
//1676 KB 312 ms #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define maxn 50005 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define root 1,n,1 using namespace std; int n; int sum[maxn<<2]; void Pushup(int rt) { sum[rt]= sum[rt<<1]+sum[rt<<1|1]; } void Build(int l,int r,int rt) { if(l==r){ scanf("%d",&sum[rt]); return ; } int m=(l+r)>>1; Build(lson); Build(rson); Pushup(rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r){ return sum[rt]; } int m=(l+r)>>1; int ans=0; if(L<=m){ ans+=query(L,R,lson); } if(R>m) ans+=query(L,R,rson); return ans; } void Update(int pos,int add,int l,int r,int rt) { if(l==r){ sum[rt]+=add; return ; } int m=(l+r)>>1; if(pos<=m){ Update(pos,add,lson); } else Update(pos,add,rson); Pushup(rt); } int main() { int cas,a,b; scanf("%d",&cas); for(int i=1;i<=cas;i++){ printf("Case %d:\n",i); scanf("%d",&n); Build(root); char ch[10]; while(scanf("%s",ch)&&ch[0]!='E'){ scanf("%d %d",&a,&b); if(ch[0]=='Q'){ printf("%d\n",query(a,b,root)); } else if(ch[0]=='A'){ Update(a,b,root); } else Update(a,-b,root); } } return 0; }