/*
translation:
给出一个数列,并且有若干操作,对某一数据增加或者减少。查询一段区间的和,给出查询的结果
solution:
线段树直接搞
note:
date:
2016.11.16
*/
#include <iostream>
#include <string>
#include <sstream>
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;
}
hdu1166(线段树)
最新推荐文章于 2019-03-16 22:28:12 发布