HDU 1166 敌兵布阵 树状数组例题
HDU 1166 敌兵布阵 树状数组题解
本题使用树状数组解决也是很好用的。
因为可以如果要求区间[a, b]的和,只记录从最小下标到b下标的和,然后减去最小下标到a-1的和,就得到区间和了
树状数组解决这类题目都很好用:
#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; class EnemyInfo_Tree_Arr_1 { static const int SIZE = 50005; int *tree; inline int lowbit(int x) { return x & (-x); } void update(int x, int val, int len) {//两边节点都需要更新?本题不需要 while (x <= len) { tree[x] += val; x += lowbit(x); } } int query(int x) { int ans = 0; while (x > 0) { ans += tree[x]; x -= lowbit(x); } return ans; } public: EnemyInfo_Tree_Arr_1() : tree((int *)malloc(sizeof(int) * SIZE)) { int T, N, a; char command[6]; scanf("%d", &T); for (int t = 1; t <= T; t++) { printf("Case %d:\n",t); scanf("%d", &N); fill(tree, tree + N+1, 0); for (int i = 1; i <= N; i++) { scanf("%d", &a); update(i, a, N); } int b, c; while (scanf("%s", command) && command[0] != 'E') { scanf("%d %d", &b, &c); if (command[0] == 'Q') printf("%d\n", query(c) - query(b-1)); else { if (command[0] == 'S') c = -c; update(b, c, N); } } } } ~EnemyInfo_Tree_Arr_1() { free(tree); } };