HDU_1166_線段樹

題意:給你一個數列,讓你維護一個區間詢問和區間查詢,線段樹或者樹狀數組:

1.線段樹代碼:

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

using namespace std;

const int N =50000 + 100;

int sum[N<<2];

void bulid(int l, int r, int rt)
{
    if(l == r)
    {
        scanf("%d", &sum[rt]);
        return ;
    }

    int m = (l+r) >> 1, rtt = rt << 1;
    bulid(l, m, rtt);
    bulid(m+1, r, rtt+1);
    sum[rt] = sum[rtt] + sum[rtt+1];
}

void update(int p, int add, int l, int r, int rt)
{
    if(l == r)
    {
        sum[rt] += add;
        return ;
    }

    int m = (l+r) >> 1, rtt = rt << 1;
    if(p <= m)  update(p, add, l, m, rtt);
    else        update(p, add, m+1, r, rtt+1);

    sum[rt] = sum[rtt] + sum[rtt+1];
}

int query(int L, int R, int l, int r, int rt)
{
    if(L<=l && r<=R)
    {
        return sum[rt];
    }

    int m = (l+r)>>1, rtt = rt<<1, ans = 0;
    if(L <= m)  ans += query(L, R, l, m, rtt);
    if(R > m)   ans += query(L, R, m+1, r, rtt+1);

    return ans;
}

int main()
{
    int t, n, a, b;
    char str[20];
    scanf("%d", &t);

    for(int i=1; i<=t; ++i)
    {
        printf("Case %d:\n", i);
        scanf("%d", &n);
        bulid(1, n, 1);

        while(scanf("%s", str))
        {
            if(str[0] == 'E') break;

            if(str[0] == 'A') scanf("%d%d", &a, &b), update(a, b, 1, n, 1);

            else if(str[0] == 'Q') scanf("%d%d", &a, &b), printf("%d\n", query(a, b, 1, n, 1));

            else if(str[0] == 'S') scanf("%d%d", &a, &b), update(a, -b, 1, n, 1);
        }
    }

    return 0;
}

2.樹狀數組代碼:

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

using namespace std;

int a[50001], c[50001];

int n;

int lowBit(int x)
{
    return x&(-x);
}

void Update(int pos, int delta)
{
    while(pos <= n)
    {
        c[pos] += delta;

        pos += lowBit(pos);
    }
}

int getresult(int pos)
{
    int sum = 0;

    while(pos > 0)
    {
        sum += c[pos];

        pos -= lowBit(pos);
    }

    return sum;
}

void Build()
{
    for(int i=1; i<=n; ++i)
    {
        scanf("%d", &a[i]);

        Update(i, a[i]);
    }
}

int main()
{
    int T, i, j, a, b;

    char s[10];

    scanf("%d", &T);

    for(i=1; i<=T; ++i)
    {
        memset(c, 0, sizeof(c));
        scanf("%d", &n);

        Build();

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

        while(scanf("%s", s) && s[0] != 'E')
        {
            scanf("%d%d", &a, &b);

            if(s[0] == 'A')
                Update(a, b);

            else if(s[0] == 'S')
                Update(a, -b);

            else
                printf("%d\n", getresult(b)-getresult(a-1));
        }
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章