您的位置:首页 > 其它

线段树单点更新模板 HDU-1166

2017-08-14 09:30 537 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

一共有三种操作:

在第i个节点增加j个人

在第i个节点减少j个人

查询i, j之间的总人数

一道线段树单点更新的模板题

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define lson ins<<1
#define rson ins<<1|1
#define merge tree[ins]=tree[lson]+tree[rson]
#define mid (r+l)/2

using namespace std;

const int Max = 50052;
int tree[Max << 2];
int data[Max << 2];

void build(int r, int l, int ins) {
if (l == r) {
tree[ins] = data[l];
} else {
build(r, mid, lson);
build(mid + 1, l, rson);
merge;
}
}

void updata(int l, int r, int ins, int en, int add) {
if (l == r) {
tree[ins] += add;
} else {
if (en <= mid)updata(l, mid, lson, en, add);
else updata(mid + 1, r, rson, en, add);
merge;
}
}

int query(int el, int er, int l, int r, int ins) {
if (el <= l && er >= r)return tree[ins];
else {
int ans = 0;
if (el <= mid)ans += query(el, er, l, mid, lson);
if (er > mid)ans += query(el, er, mid + 1, r, rson);
return ans;
}
}

int main() {
int T, cases = 1;
scanf("%d", &T);
while (T--) {
int n;
scanf("%d", &n);
for (int a = 1; a <= n; a++) {
scanf("%d", &data[a]);
}
build(1, n, 1);
char opera[10];
int ip, add;
printf("Case %d:\n", cases++);
while (~scanf("%s", opera)) {
if (opera[0] == 'E')break;
scanf("%d%d", &ip, &add);
if (opera[0] == 'A') {
updata(1, n, 1, ip, add);
} else if (opera[0] == 'S') {
updata(1, n, 1, ip, -add);
} else if (opera[0] == 'Q') {
printf("%d\n", query(ip, add, 1, n, 1));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线段树单点更新