HDU1166-敌兵布阵(单点修改,区间查询)
题意简述:
\(T\)组样例,每组样例给出\(n\)个军队,每个军队的人数为\(a_i\)。
四种操作:
(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\)表示结束,这条命令在每组数据最后出现;
思路:
线段树入门题,单点修改,区间操作,此处不对线段树进行讲解,仅用作复习。
Code:
#include<bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mid (l+r)/2
using namespace std;
const int maxn=2e5+10;
//单点修改 区间查询
int t,x,y,n;
char s[10];
int q[maxn];
struct node{
int tr[maxn],lazy[maxn];
void pushup(int rt){
tr[rt]=tr[rt<<1]+tr[rt<<1|1];
}
void pushdown(int l,int r,int rt){
}
void build(int l,int r,int rt){
if(l==r){
tr[rt]=q[l];
return ;
}
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int l,int r,int rt,int val){
if(L<=l&&r<=R){
tr[rt]+=val;
return ;
}
if(L<=mid){
update(L,R,l,mid,rt<<1,val);
}
if(R>mid){
update(L,R,mid+1,r,rt<<1|1,val);
}
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return tr[rt];
}
int sum=0;
if(L<=mid){
sum=sum+query(L,R,lson);
}
if(R>mid){
sum=sum+query(L,R,rson);
}
return sum;
}
}sgt;
int main(){
scanf("%d",&t);
int ca=0;
while(t--){
scanf("%d",&n);
ca++;
for(int i=1;i<=n;++i){
scanf("%d",&q[i]);
}
sgt.build(1,n,1);
printf("Case %d:\n",ca);
while(scanf("%s",s)&&s[0]!='E'){
scanf("%d%d",&x,&y);
if(s[0]=='Q'){
printf("%d\n",sgt.query(x,y,1,n,1));
}
else if(s[0]=='A'){
sgt.update(x,x,1,n,1,y);
}
else{
sgt.update(x,x,1,n,1,-y);
}
}
}
return 0;
}