题目链接: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; }
思考:有几个坑点,首先是输入。仔细想一想就能够得出答案,对于a[i]来讲,输入后要将其加到所有能够覆盖到a[i]的c中。
然后树状数组的核心就是low-bit。update,sum沿着树向上向下的操作。
自己现在已经懒得去思考什么了,干就完事儿了。