HDU 1166 敌兵布阵 数据结构-树状数组-改点查段

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

一篇很好的树状数组的讲解:https://blog.csdn.net/flushhip/article/details/79165701

解题思路:弄清树状数组的原理就好,以前自己是为了打比赛而做题,现在自己是为了学习而做题。

代码:

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

using namespace std;
const int MAXN = 50007;

int a[MAXN];
int n;

int low_bit(int k) {
    return k & -k;
}
void update(int i, int val) {
    while(i <= n) {
        a[i] += val;
        i += low_bit(i);
    }
}
int sum(int k) {
    int ret = 0;
    while(k > 0) {
        ret += a[k];
        k -= low_bit(k);
    }
    return ret;
}
int main() {
    //freopen("in.txt","r",stdin);
    char s[19];
    int t;
    int cases = 0;
    cin >> t;
    //scanf("%d", &t);
    while(t--) {
        memset(a, 0, sizeof(a));
        printf("Case %d:
", ++cases);
    
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            int temp;
            scanf("%d", &temp);
            update(i, temp);
        }
        
       
        for(int i = 1; i <= n; i++) {
            cout << a[i] << " ";
        }
        cout << endl;
        scanf("%s", s);
        while(s[0] != 'E') {
            int b, c;
            scanf("%d%d", &b, &c);
            if(s[0] == 'A') {
                update(b, c);
            }
            else if(s[0] == 'S') {
                update(b, -c);
            }
            else {
                
                printf("%d
", sum(c)-sum(b-1));
            }
            scanf("%s", s);
        }
    }
    return 0;
}
View Code

思考:有几个坑点,首先是输入。仔细想一想就能够得出答案,对于a[i]来讲,输入后要将其加到所有能够覆盖到a[i]的c中。

   然后树状数组的核心就是low-bit。update,sum沿着树向上向下的操作。

   自己现在已经懒得去思考什么了,干就完事儿了。

原文地址:https://www.cnblogs.com/FriskyPuppy/p/10201495.html