Title: hdoj1166
Analysis: the meaning of the question is very clear, that is, let you add or reduce X to a certain point, and then find the number of a certain segment. I use a father array to save the number of leaf nodes, then it starts from the current node and becomes lighter to the root node.
If you look at the left subinterval or right subinterval from the root node, you can directly query a certain segment within the range to be queried. The sum is OK, which is very simple.
Code:
#include <cstdio>#include <string>#include <iostream>using namespace std;const int N = 55000;struct Node{ int l,r; int sum;};Node tree[4*N];int a[N];int fa[N];void build(int l,int r,int v){ tree[v].l=l; tree[v].r=r; if(l==r) { fa[l]=v; tree[v].sum=a[l]; return ; } int mid=(l+r)>>1; build(l,mid,v*2); build(mid+1,r,v*2+1); tree[v].sum=tree[v+v].sum+tree[v+v+1].sum;}void update(int t,int p){ tree[t].sum+=p; if(t==1) return ; update(t/2,p);}int queue(int a,int b,int v){ if(tree[v].l==a&&tree[v].r==b) { return tree[v].sum; } int mid=(tree[v].l+tree[v].r)>>1; if(b<=mid) return queue(a,b,v+v); else if(a>mid) return queue(a,b,v+v+1); else return queue(a,mid,v*2)+queue(mid+1,b,v*2+1);}int main(){ int T,n; char str[10]; int x,y; scanf("%d",&T); for(int cas=1; cas<=T; cas++) { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); build(1,N,1); printf("Case %d:\n",cas); while(scanf("%s",str)>0) { if(str[0]==‘A‘) { scanf("%d %d",&x,&y); update(fa[x],y); } else if(str[0]==‘S‘) { scanf("%d %d",&x,&y); update(fa[x],-y); } else if(str[0]==‘Q‘) { scanf("%d %d",&x,&y); int ans=queue(x,y,1); printf("%d\n",ans); } else { break; } } }}
Single point update sum of line tree hdoj1166