地址:http://acm.hdu.edu.cn/showproblem.php?pid=1166

题意:给n个数字。对这n个数字有3种操作:1. add 2.sub 3.query。分别对应把某数增加或减少一个值和查询某[l,r]区间内所有值的和。

mark:最基本的线段树or树状数组的应用。话说树状数组真是简洁啊!

代码:

线段树

hdu 1166_i++hdu 1166_线段树_02
 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 }
View Code

树状数组

hdu 1166_i++hdu 1166_线段树_02
 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 }
View Code