题目链接
HDU1166
- 大量输入输出
printf&scanf
,可能字符串要求操作的地方使用strcmp会更好一点 - 查询的问题可能会大一些,注意考虑到涉及的所有区间
- 数组开大
- 维护的区间和在进行变更值操作的时候都要写上
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 50005;
int n,T;
struct SengmentTree{
int l,r;
int sum;
}a[N*4];
int t[N],ANS=0;
//p代表lr区间
void build(int p,int l,int r){
a[p].l = l;
a[p].r = r;
if(l == r){//叶子节点
a[p].sum = t[l];
return ;
}
int mid = (l + r) / 2;
build(p*2,l,mid);//左子区间
build(p*2+1,mid+1,r);//右子区间
a[p].sum = a[2*p].sum + a[2*p+1].sum;
}
void change(int p,int x,int v){
if(a[p].l == a[p].r){//叶子节点
a[p].sum+=v;
return ;
}
int mid = (a[p].l + a[p].r) >> 1;
if(x <= mid)
change(p*2,x,v);//左子区间找
else
change(p*2+1,x,v);//右子区间找
//更新信息
a[p].sum = a[2*p].sum + a[2*p+1].sum;
}
void ask(int p,int l,int r){
if(l<=a[p].l&&r>=a[p].r)
ANS += a[p].sum;
else{
int mid = (a[p].l + a[p].r) >> 1;
if(r<=mid)
ask(p*2,l,r);
else if(l>mid)
ask(p*2+1,l,r);
else{
ask(p*2,l,mid);
ask(p*2+1,mid+1,r);
}
}
}
int main(){
cin>>T;
int i = 1;
while(T--){
memset(t,0,sizeof(t));
printf("Case %d:\n",i++);
cin>>n;
for(int i = 1;i<=n;i++){
scanf("%d",&t[i]);
}
build(1,1,n);
char flag[10];
while(scanf("%s",flag)&&flag[0]!='E'){
if(flag[0]=='A'){
int x,v;
scanf("%d%d",&x,&v);
change(1,x,v);
}
if(flag[0]=='S'){
int x,v;
scanf("%d%d",&x,&v);
change(1,x,-v);
}
if(flag[0] == 'Q'){
int l,r;
scanf("%d%d",&l,&r);
ask(1,l,r);
printf("%d\n",ANS);
ANS = 0;
}
}
}
return 0;
}