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:
",++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
",ans);
			}
			else{
				if(strcmp(s,"Sub")==0)
				b=-b;
				a=pos[a];
				update(a,b);
			}
		}
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/jie-dcai/p/4314398.html