#include <bits/stdc++.h>
#define N 10010
using namespace std;
int tre[N*4];
void build(int num,int le,int ri){
if(le==ri){
scanf("%d",&tre[num]);
return ;
}
int mid=(le+ri)/2;
build(num*2,le,mid);
build(num*2+1,mid+1,ri);
tre[num]=tre[num*2]+tre[num*2+1];
}
void update(int num,int le,int ri,int x,int y){
if(le==ri){
tre[num]+=y;
return ;
}
int mid=(le+ri)/2;
if(x<=mid)update(num*2,le,mid,x,y);
else update(num*2+1,mid+1,ri,x,y);
tre[num]=tre[num*2]+tre[num*2+1];
}
int query(int num,int le,int ri,int x,int y)
{
if(x<=le&&y>=ri)return tre[num];
int mid=(le+ri)/2;
int ans=0;
if(x<=mid)ans+=query(num*2,le,mid,x,y);
if(y>mid)ans+=query(num*2+1,mid+1,ri,x,y);
return ans;
}
int main(void){
int t;cin>>t;
while(t--){
int n;cin>>n;
build(1,1,n);
string ope;
while(1){
cin>>ope;
if(ope=="End"){
break;
}
else if(ope=="Query"){
int a,b;cin>>a>>b;
cout<<query(1,1,n,a,b)<<endl;
}
else if(ope=="Add"){
int a,b;cin>>a>>b;
update(1,1,n,a,b);
}
else if(ope=="Sub"){
int a,b;cin>>a>>b;
update(1,1,n,a,(-1)*b);
}
}
}
return 0;
}
线段树单点更新
题目:HDU1166
输入N个数的序列,有增减查及结束四种操作,对每个查询返回区间内的和
Input output
1 6
10 33
1 2 3 4 5 6 7 8 9 10 59
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
*/
精简模板
#include <bits/stdc++.h>
using namespace std;
int tre[103*4];
void update(int num,int le,int ri,int x,int y){
if(le==ri){tre[num]+=y;return ;}
int mid=(le+ri)/2;
if(x<=mid)update(num*2,le,mid,x,y);
else update(num*2+1,mid+1,ri,x,y);
tre[num]=tre[num*2]+tre[num*2+1];
}
int query(int num,int le,int ri,int x,int y){
int ans=0;
if(x<=le&&ri<=y)return tre[num];
int mid=(le+ri)/2;
if(x<=mid)ans+=query(num*2,le,mid,x,y);
if(y>mid)ans+=query(num*2+1,mid+1,ri,x,y);
return ans;
}
int main(void){
int n;cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
update(1,1,n,i,x);
}
int x,y;cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
return 0;
}
/*
5
1 2 3 4 5
2 4
*/