HDOJ 1166 - 敌兵布阵

来源:互联网 发布:网络主播哪一年兴起的 编辑:程序博客网 时间:2024/05/29 19:37

Advanced Data Structures :: Segment Tree


Description

敌人的军队驻扎在各个营地里,告诉你各个营地里有多少人,

请计算从第i个营地到第j个营地一共有多少人。

同时,敌人营地里的人数可能发生改变,因此会有三种操作——增加、减少、询问。

输出每次询问的结果。


Type

Advanced Data Structures :: Segment Tree

Advanced Data Structures :: Binary Indexed Tree


Analysis

经典的线段树题目,也是经典的树状数组的题目。

可以用线段树和树状数组两种方法来实现。

数状数组和线段树相比,复杂度相当,但是常数更小,速度更快、空间消耗更小,且编程复杂度较低。

但数状数组没有线段树功能那么的强大,例如无法求解RMQ问题。


Solution

1. Segment Tree

// HDOJ 1166// 敌兵布阵// by A Code Rabbit#include <cstdio>#include <cstring>#define LSon(x) (x << 1) #define RSon(x) (x << 1 | 1)const int MAXN = 50002;const int ROOT = 1;struct Seg{    int w;};struct SegTree {    Seg node[MAXN << 2];    void Update(int pos) { node[pos].w = node[LSon(pos)].w + node[RSon(pos)].w; }    void Build(int l, int r, int pos) {        if (l == r) { scanf("%d", &node[pos].w); return; }        int m = l + r >> 1;        Build(l, m, LSon(pos));        Build(m + 1, r, RSon(pos));        Update(pos);    }    void Modify(int l, int r, int pos, int x, int y) {        if (l == r) { node[pos].w += y; return; }        int m = l + r >> 1;        if (x <= m) Modify(l, m, LSon(pos), x, y);        else Modify(m + 1, r, RSon(pos), x, y);        Update(pos);    }    int Query(int l, int r, int pos, int x, int y) {        if (x <= l && r <= y) return node[pos].w;        int m = l + r >> 1;        int res = 0;        if (x <= m) res += Query(l, m, LSon(pos), x, y);        if (y > m) res += Query(m + 1, r, RSon(pos), x, y);        return res;    }};int n;char cmd[20];int x, y;SegTree tree;int main() {    int tot_case = 0;    scanf("%d", &tot_case);    for (int t = 0; t < tot_case; t++) {        scanf("%d", &n);        tree.Build(1, n, ROOT);        printf("Case %d:\n", t + 1);        while (1) {            getchar();            scanf("%s", cmd);            if (!strcmp(cmd, "Add")) {                scanf("%d%d", &x, &y);                tree.Modify(1, n, ROOT, x, y);            } else            if (!strcmp(cmd, "Sub")) {                scanf("%d%d", &x, &y);                tree.Modify(1, n, ROOT, x, -y);            } else            if (!strcmp(cmd, "Query")) {                scanf("%d%d", &x, &y);                printf("%d\n", tree.Query(1, n, ROOT, x, y));            } else            if (!strcmp(cmd, "End")) {                break;            }        }    }    return 0;}

2. Binary Indexed Tree
// HDOJ 1166// 敌兵布阵// by A Code Rabbit#include <cstdio>#include <cstring>const int MAXN = 50002;struct Bit {    int c[MAXN], n;    void Init(int x) { memset(c, 0, sizeof(c)); n = x; }    void Add(int x, int y) {        while (x <= n) { c[x] += y; x += x & -x; }    }    int Sum(int x) {        int res = 0;        while (x > 0) { res += c[x]; x -= x & -x; }        return res;    }};int n;int a[MAXN];char command[10];int p, q;Bit bit;int main() {    int tot_case;    scanf("%d", &tot_case);    for (int t = 0; t < tot_case; t++) {        scanf("%d", &n);        bit.Init(n);        for (int i = 0; i < n; i++) {            scanf("%d", &a[i]);            bit.Add(i + 1, a[i]);        }        printf("Case %d:\n", t + 1);        while (scanf("%s", command) && strcmp(command, "End") != 0) {            scanf("%d%d", &p, &q);            if (strcmp(command, "Add") == 0)                bit.Add(p, q);            else if (strcmp(command, "Sub") == 0)                bit.Add(p, -q);            else if (strcmp(command, "Query") == 0)                printf("%d\n", bit.Sum(q) - bit.Sum(p - 1));        }    }    return 0;}

原创粉丝点击