hdu 1754 I Hate It(树状数组区间求最值)2007省赛集训队练习赛(6)_linle专场

题意:

输入一行数字,查询第i个数到第j个数之间的最大值。可以修改其中的某个数的值。

 

输入:

包含多组输入数据。

每组输入首行两个整数nm。表示共有n个数,m次操作。

接下来一行包含n个整数。

接下来m行,每行包含一个字母s,两个整数ab

s’Q’,表示查询第a个数到第b个数之间的最大值。

s’U’,表示将第a个数更改为b

 

输出:

每次查询输出一个结果,每次输出占一行。

 

题解:

点修改区间求最值,可以用树状数组模板。

 

具体见代码——

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N = 200010;
 8 
 9 int a[N], c[N];
10 int t, n, m;
11 
12 int lowbit(int x)
13 {
14     return x&(-x);
15 }
16 
17 void Maxn(int x, int y)
18 {
19     a[x] = y;
20     for(int i = x; i <= n; i += lowbit(i))              //需要修改的c[]
21     {
22         c[i] = y;
23         for(int j = 1; j < lowbit(i); j <<= 1)          //修改时需要比较的c[]
24         {
25             c[i] = c[i] > c[i-j] ? c[i] : c[i-j];
26         }
27     }
28 }
29 
30 void Init()
31 {
32     int  y;
33     memset(c, 0, sizeof(c));
34     for(int i = 1; i <= n; i++)
35     {
36         scanf("%d", &y);
37         a[i] = y;
38         c[i] = y;
39         for(int j = 1; j <lowbit(i); j <<= 1)           //需要比较的c[]
40             c[i] = c[i] > c[i-j] ? c[i] : c[i-j];
41     }
42 }
43 
44 void Query(int l, int r)
45 {
46     int ans = 0;
47     while(1)
48     {
49         ans = ans > a[r] ? ans : a[r];
50         if(r == l) break;
51         for(r -= 1; r-l >= lowbit(r); r -= lowbit(r))
52             ans = ans > c[r] ? ans : c[r];
53     }
54     printf("%d\n", ans);
55 }
56 
57 void Work()
58 {
59     char s[2];
60     int x, y;
61     for(int i = 1; i <= m; i++)
62     {
63         scanf("%s%d%d", s, &x, &y);
64         if(s[0] == 'U') Maxn(x, y);
65         else if(s[0] == 'Q') Query(x, y);
66     }
67 }
68 
69 int main()
70 {
71     //freopen("test.in", "r", stdin);
72     while(~scanf("%d%d", &n, &m))
73     {
74         Init();
75         Work();
76     }
77 }
View Code

树状数组区间求最值模板——

 http://www.cnblogs.com/mypride/p/5002556.html

posted @ 2015-11-28 13:40  mypride  阅读(297)  评论(0编辑  收藏  举报