HDU 1166
线段树单点更新,区间求和。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string.h> #include <queue> #include <cmath> #include <map> #include <vector> #define LL __int64 using namespace std; const int N=50010; const int root=1; struct Node{ int val; int left,right; }tree[N*4+100]; int pos[N],n,val[N],ans; char s[10]; void build(int now,int l,int r){ if(l==r){ tree[now].val=val[l]; tree[now].left=l; tree[now].right=r; pos[l]=now; return ; } tree[now].val=0; tree[now].left=l; tree[now].right=r; build(now*2,l,(l+r)/2); build(now*2+1,(l+r)/2+1,r); tree[now].val+=(tree[now*2].val+tree[now*2+1].val); } void query(int rt,int l,int r){ int L=tree[rt].left,R=tree[rt].right; if(l<=L&&r>=R){ ans+=tree[rt].val; return; } int m=(L+R)/2; if(r<=m){ query(rt*2,l,r); } else if(l>=m+1){ query(rt*2+1,l,r); } else{ query(rt*2,l,r); query(rt*2+1,l,r); } } void update(int now,int s){ while(now>=root){ tree[now].val+=s; now/=2; } } int main(){ int T,a,b,t=0; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&val[i]); memset(pos,0,sizeof(pos)); build(root,1,n); printf("Case %d:\n",++t); while(scanf("%s",s)&&strcmp(s,"End")!=0){ scanf("%d%d",&a,&b); ans=0; if(strcmp(s,"Query")==0){ query(root,a,b); printf("%d\n",ans); } else{ if(strcmp(s,"Sub")==0) b=-b; a=pos[a]; update(a,b); } } } return 0; }