hdu 1754

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

题意:给n个数字。m次操作,每次操作更新一个数字或者查询区间最大值。

mark:典型线段树题。不过a的时候学了一下树状数组求区间最值。感觉对树状数组的理解又深刻了一点。不过这个更新不是O(lgn)而是O(lgn*lgn)的,比线段树慢!

代码:

线段树:

 1 # include <stdio.h>
 2 # include <string.h>
 3 
 4 
 5 #define max(a,b) (a>b?a:b)
 6 int n ;
 7 int tr[200010<<2] ;
 8 
 9 
10 void u(int a, int b, int l, int r, int rt)
11 {    
12     int m = (l+r)/2 ;
13     if (l == r) {
14         tr[rt] = b;
15         return;
16     }
17     if (a <= m) u(a, b, l, m, rt*2);
18     else u(a, b, m+1, r, rt*2+1);
19     tr[rt] = max(tr[rt*2], tr[rt*2+1]);
20 }
21 
22 
23 int q(int a, int b, int l, int r, int rt)
24 {
25     int m = (l + r) / 2, a1, a2 ;
26     if (a == l && b == r) return tr[rt];
27     if (b <= m) return q(a, b, l, m, rt*2) ;
28     else if (a > m) return q(a, b, m+1, r, rt*2+1) ;
29     a1 = q(a, m, l, m, rt*2), a2 = q(m+1, b, m+1, r, rt*2+1) ;
30     return max(a1, a2) ;
31 }
32 
33 
34 int main ()
35 {
36     int m, i, a, b ;
37     char op[5] ;
38     
39     while (~scanf ("%d%d", &n, &m))
40     {
41         //memset (tr, 0, sizeof(tr));
42         for (i = 1 ; i <= n ; i++)
43             scanf ("%d", &a), u(i, a, 1, n, 1);
44         while (m--)
45         {
46             scanf ("%s %d %d", op, &a, &b) ;
47             if (op[0] == 'U') u(a, b, 1, n, 1);
48             else printf ("%d
", q(a, b, 1, n, 1)) ;
49         }
50     }
51     return 0 ;
52 }
View Code

树状数组(不加inline优化max函数的话会TLE!!!)

 1 # include <stdio.h>
 2 # include <string.h>
 3 
 4 
 5 int n, num[200010], tr[200010];
 6 int lowbit(int x){return x & -x;}
 7 inline int max(int a, int b){return a>b?a:b;}
 8 
 9 
10 void u(int a, int b){
11     int i, j;
12     num[a] = b;
13     for (i = a; i <= n; i+=lowbit(i))
14     {
15         tr[i] = num[i];
16         for (j = 1; j < lowbit(i); j <<= 1)
17             tr[i] = max(tr[i], tr[i-j]);
18     }
19 }
20 
21 
22 int q(int a, int b){
23     int i = b, ans = num[b];
24     while (i >= a)
25         if (i-lowbit(i)+1 >= a)
26             ans = max(ans, tr[i]), i -= lowbit(i);
27         else
28             ans = max(ans, num[i]), i--;
29     return ans;
30 }
31 
32     
33 int main ()
34 {
35     int a, b, i, m;
36     char op[5];
37     while (~scanf ("%d%d", &n, &m))
38     {
39         memset(tr, 0, sizeof(tr));
40         for (i = 1; i <= n; i++)
41             scanf ("%d", &a), u(i, a);
42         while (m--)
43         {
44             scanf ("%s %d %d", op, &a, &b);
45             if (op[0] == 'U') u(a, b);
46             else printf ("%d
", q(a, b)) ;
47         }
48     }
49     return 0 ;
50 }
View Code
原文地址:https://www.cnblogs.com/lzsz1212/p/3456800.html