hdu1166(线段树)

/*
translation:
	给出一个数列,并且有若干操作,对某一数据增加或者减少。查询一段区间的和,给出查询的结果
solution:
	线段树直接搞
note:
date:
	2016.11.16
*/
#include 
#include 
#include 

using namespace std;
const int maxn = 50000 + 5;

struct Node
{
	int L, R, sum;
	Node(int l, int r, int s):L(l),R(r),sum(s){}
	Node(){}
	int mid(){ return (L + R) / 2; }
} nodes[6 * maxn];

int a[maxn], n, q;

void build_tree(int root, int L, int R)
{
	nodes[root].L = L;
	nodes[root].R = R;
	nodes[root].sum = 0;

	if(L != R){
		build_tree(root * 2 + 1, L, (L + R) / 2);
		build_tree(root * 2 + 2, (L + R) / 2 + 1, R);
	}
}

void insert_tree(int root, int k, int val)
{
	if(nodes[root].L == nodes[root].R){
		nodes[root].sum += val;
		return;
	}

	nodes[root].sum += val;

	if(k <= nodes[root].mid())	insert_tree(root * 2 + 1, k, val);
	else 						insert_tree(root * 2 + 2, k, val);
}

int query(int root, int L, int R)
{
	if(nodes[root].L == L && nodes[root].R == R)	return nodes[root].sum;

	if(R <= nodes[root].mid())	return query(root * 2 + 1, L, R);
	else if(L > nodes[root].mid())	return query(root * 2 + 2, L, R);
	else{
		return query(root*2+1, L, nodes[root].mid())
			+ query(root*2+2, nodes[root].mid()+1, R);
	}
}

int main()
{
	//freopen("in.txt", "r", stdin);
    int T, kase = 0;
    scanf("%d", &T);
    while(T--){
		scanf("%d", &n);
		build_tree(0, 1, n);

		for(int i = 1; i <= n; i++){
			scanf("%d", &a[i]);
			insert_tree(0, i, a[i]);
		}

		printf("Case %d:\n", ++kase);

		string line, op;
		int x, y;
		while(getline(cin, line)){
			if(line == "End")	break;

			stringstream ss(line);
			ss >> op >> x >> y;

			if(op == "Add"){
				//cout << "Add" << endl;
				insert_tree(0, x, y);
			}else if(op == "Sub"){
				//cout << "Sub" << endl;
				insert_tree(0, x, -y);
			}else if(op == "Query"){
				//cout << "Query" << endl;
				printf("%d\n", query(0, x, y));
			}
		}
    }
    return 0;
}

你可能感兴趣的:(=====数据结构=====,线段树)