1 10 1 2 3 4 5 6 7 8 9 10 Query 1 3 Add 3 6 Query 2 7 Sub 10 2 Add 6 3 Query 3 10 End
Case 1: 6 33 59
又做了一个树状数组的题,,感觉蛮好玩的!
AC代码:
#include <cstdio> #include <cstring> using namespace std; const int MAX = 50005; int a[MAX], n; int lowbit(int x) { return x&(-x); } void add(int t, int d) { while(t<=n) { a[t] += d; t += lowbit(t); } } int sum(int t) { int ret = 0; while(t>0) { ret += a[t]; t -= lowbit(t); } return ret; } int main() { int T, cas = 1, tmp; scanf("%d", &T); while(T--) { memset(a, 0, sizeof(a)); scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", &tmp); add(i, tmp); } printf("Case %d:\n", cas++); char str[10]; while(1) { int t1, t2; scanf("%s", str); if(strcmp(str, "End") == 0) break; scanf("%d %d", &t1, &t2); if(strcmp(str, "Query") == 0) printf("%d\n", sum(t2)-sum(t1-1)); else if(strcmp(str, "Add") == 0) add(t1, t2); else if(strcmp(str, "Sub") == 0) add(t1, (-1)*t2); } } return 0; }
====================================================================================
2015/3/18 19:23更新此博客
用线段树再次做了这题,也练习练习线段树。。
线段树功能:update:单点增减 query:区间求和
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 50005; int sum[maxn<<2]; //这里是维护区间和 void pushup(int rt) {//把当前结点的信息更新到父结点,rt表示当前子树的根(root),也就是当前所在的结点 sum[rt] = sum[rt<<1] + sum[rt<<1|1];//位运算,rt<<1等价于rt*2,rt<<1|1等价于rt*2+1; } void build(int l, int r, int rt) { //建立线段树 if(l == r) { scanf("%d", &sum[rt]); return; } int m = (l + r) >> 1; build(l, m, rt << 1); build(m + 1, r, rt << 1 | 1); pushup(rt); } void update(int p, int add, int l, int r, int rt) { //单点更新 if(l == r) { sum[rt] += add; return ; } int m = (l + r) >> 1; if(p <= m) update(p, add, l, m, rt << 1); else update(p, add, m + 1, r, rt << 1 | 1); pushup(rt); } 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; int ret = 0; if(L <= m) ret += query(L, R, l, m, rt << 1); if(R > m) ret += query(L, R, m + 1, r, rt << 1 | 1); return ret; } int main() { int T, n, cas = 1; scanf("%d", &T); while(T--) { printf("Case %d:\n", cas++); scanf("%d", &n); build(1, n, 1); char ord[10]; while(1) { scanf("%s", ord); if(ord[0] == 'E') break; int a, b; scanf("%d %d", &a, &b); if(ord[0] == 'Q') printf("%d\n", query(a, b, 1, n, 1)); else if(ord[0] == 'A') update(a, b, 1, n, 1); else update(a, -b, 1, n, 1); } } return 0; }