HDOJ 1166 敌兵布阵(线段树基本操作)

思路:

基本的线段树操作:单点更新,区间求和

#include <cstdio>

#include <cstdlib>

#include <cstring>



#define lhs l, m, rt << 1

#define rhs m + 1, r, rt << 1 | 1



const int maxn = 50010;

int seg[maxn << 2];



void PushUp(int rt)

{

    seg[rt] = seg[rt << 1] + seg[rt << 1 | 1];

}



void Build(int l, int r, int rt)

{

    if (l == r)

        scanf("%d", &seg[rt]);

    else

    {

        int m = (l + r) >> 1;

        Build(lhs);

        Build(rhs);

        PushUp(rt);

    }

}



void Update(int p, int delta, int l, int r, int rt)

{

    if (l == r)

        seg[rt] += delta;

    else

    {

        int m = (l + r) >> 1;

        if (p <= m)

            Update(p, delta, lhs);

        else

            Update(p, delta, rhs);

        PushUp(rt);

    }

}



int Query(int beg, int end, int l, int r, int rt)

{

    if (beg <= l && r <= end)

        return seg[rt];



    int m = (l + r) >> 1;

    int ret = 0;

    if (beg <= m)

        ret += Query(beg, end, lhs);

    if (end > m)

        ret += Query(beg, end, rhs);



    return ret;

}



int main()

{

    int cases;

    scanf("%d", &cases);



    for (int t = 1; t <= cases; ++t)

    {

        int n;

        scanf("%d", &n);

        Build(1, n, 1);



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



        char op[16];

        while (scanf("%s", op) && op[0] != 'E')

        {

            int a, b;

            scanf("%d %d", &a, &b);



            if (op[0] == 'Q')

                printf("%d\n", Query(a, b, 1, n, 1));

            else if (op[0] == 'A')

                Update(a, b, 1, n, 1);

            else if (op[0] == 'S')

                Update(a, -b, 1, n, 1);

        }

    }

    return 0;

}

 

 

 

你可能感兴趣的:(基本操作)