HDU 1166 (segment tree)

本文介绍了一个简单的段树实现问题,旨在帮助读者理解并实践段树数据结构的应用。文章提供了完整的C++代码示例,展示了如何构建段树、更新节点值以及查询区间和等操作。

An easy problem aiming at practicing the implementation of the segment tree. Apparently, we should use segment tree to solve it. And within the tree structure is the sum.

Note that the number of the nodes is much larger than the size of the integer array because of the "tree" structure. Otherwise, it may cause Runtime Error (ACCESS_VIOLATION).

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 0x3f3f3f3f
#define N 50010
#define MST(a,b) memset(a,b,sizeof(a))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

struct TREE {
    int left,right;
    int suml;
} tree[900000];//*** Large Enough? ***

void Built(int root,int l,int r){
    tree[root].left = l;
    tree[root].right = r;
    tree[root].suml=0;
    if(l == r)return;
    int mid = (l+r) >> 1;
    Built ( root<<1   , l , mid );
    Built ( root<<1|1 , 1+mid , r);
}

void Fix(int root,int left,int right,int del) {
    if (left == tree[root].left && tree[root].right == right) {
        tree[root].suml += del;
        return;
    }    if (left < tree[root].left || right > tree[root].right)
        return;
    Fix(root << 1, left, right, del);
    Fix(root << 1 | 1, left, right, del);
    tree[root].suml += del;
}

int Query_sum(int root,int left,int right) {
    if (left == tree[root].left && tree[root].right == right)
        return tree[root].suml;
    if (tree[root << 1 | 1].left > right)//left only
        return Query_sum(root << 1, left, right);
    if (left > tree[root << 1].right)//right only
        return Query_sum(root << 1 | 1, left, right);
    int s1 = 0, s2 = 0;
    s1 = Query_sum(root << 1, left, tree[root << 1].right);
    s2 = Query_sum(root << 1 | 1, tree[root << 1 | 1].left, right);
    return s1 + s2; 
    if (left < tree[root].left || right > tree[root].right)
        return -INF;
}


int main(){
    int t,n,a,b;
    cin>>t;
    FOR(ncase,1,t) {
        printf("Case %d:\n", ncase);
        cin >> n;
        Built(1, 1, n);
        FOR(i, 1, n) {
            cin >> a;
            Fix(1, i, i, a);
        }
        char s[10];
        cin >> s;
        while (s[0] != 'E') {
            cin >> a >> b;
            if (s[0] == 'A') {
                Fix(1, a, a, b);
            }
            else if (s[0] == 'S') {
                Fix(1, a, a, -b);
            }
            else
                printf("%d\n", Query_sum(1, a, b));
            cin>>s;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值