地址:http://acm.hdu.edu.cn/showproblem.php?pid=1166
题意:给n个数字。对这n个数字有3种操作:1. add 2.sub 3.query。分别对应把某数增加或减少一个值和查询某[l,r]区间内所有值的和。
mark:最基本的线段树or树状数组的应用。话说树状数组真是简洁啊!
代码:
线段树
1 # include <stdio.h> 2 # include <string.h> 3 4 5 int n, tr[50010<<2] ; 6 7 8 void add(int a, int b, int l, int r, int rt) 9 { 10 int m = (l+r)/2 ; 11 tr[rt] += b; 12 if (l == r) return; 13 if (a <= m) add (a, b, l, m, rt*2) ; 14 else add (a, b, m+1, r, rt*2+1) ; 15 } 16 17 18 int query (int a, int b, int l, int r, int rt) 19 { 20 int m, rtn ; 21 if (l == a && r == b) return tr[rt] ; 22 m = (l+r)/2 ; 23 if (b <= m) return query(a, b, l, m, rt*2) ; 24 if (a > m) return query (a, b, m+1, r, rt*2+1) ; 25 return query(a, m, l, m, rt*2) + query (m+1, b, m+1, r, rt*2+1) ; 26 } 27 28 29 int main () 30 { 31 int T, nCase = 1; 32 int i, num, a, b ; 33 char order[10] ; 34 scanf ("%d", &T) ; 35 while (T--) 36 { 37 memset (tr, 0, sizeof(tr)) ; 38 printf ("Case %d:\n", nCase++) ; 39 scanf ("%d", &n) ; 40 for (i = 1 ; i <= n ; i++) 41 scanf ("%d", &num), add(i, num, 1, n, 1) ; 42 while (1) 43 { 44 scanf ("%s", order) ; 45 if (!strcmp(order, "End")) break ; 46 scanf ("%d%d", &a, &b) ; 47 if (!strcmp(order, "Query")) 48 printf ("%d\n", query(a, b, 1, n, 1)); 49 else if (!strcmp(order, "Sub")) 50 add (a, -b, 1, n, 1) ; 51 else add (a, b, 1, n, 1) ; 52 } 53 } 54 return 0 ; 55 }
树状数组
1 # include <stdio.h> 2 # include <string.h> 3 4 5 int bit[50010] ; 6 int n ; 7 8 9 int lowbit (int x){return x & -x;} 10 11 12 void add (int a, int b) 13 { 14 while (a <= n) 15 bit[a] += b, a += lowbit(a); 16 } 17 18 19 int q(int a) 20 { 21 int ans = 0 ; 22 while (a) 23 ans += bit[a], a -= lowbit(a); 24 return ans ; 25 } 26 27 28 int main () 29 { 30 int T, i, nCase = 1, a, b ; 31 char ord[10] ; 32 scanf ("%d", &T) ; 33 while (T--) 34 { 35 memset (bit, 0, sizeof(bit)) ; 36 scanf ("%d", &n) ; 37 for (i = 1 ; i <= n ; i++) 38 scanf ("%d", &a), add (i, a) ; 39 printf ("Case %d:\n", nCase++) ; 40 while (~scanf ("%s", ord) && strcmp(ord, "End")) 41 { 42 scanf ("%d%d", &a, &b) ; 43 if (!strcmp(ord, "Query")) 44 printf ("%d\n", q(b) - q(a-1)) ; 45 else if (!strcmp(ord, "Sub")) 46 add (a, -b) ; 47 else add (a, b) ; 48 } 49 } 50 return 0 ; 51 }