hdu 1754 块状链表 单点修改+单点查询

经典的线段树题目,也可以用块状链表做。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cmath>
  5 using namespace std;
  6 
  7 const int N = 200000;
  8 const int M = 800;
  9 int n, m, tot;
 10 
 11 int max( int a, int b )
 12 {
 13     return a > b ? a : b;
 14 }
 15 
 16 struct Block
 17 {
 18     int num[M];
 19     int size, maxn;
 20     void init()
 21     {
 22         size = maxn = 0;
 23     }
 24     void push( int tmp )
 25     {
 26         num[size++] = tmp;
 27         if ( tmp > maxn ) maxn = tmp;
 28     }
 29 } bl[M];
 30 
 31 void update( int pos, int v )
 32 {
 33     int cur = 0;
 34     while ( pos > bl[cur].size )
 35     {
 36         pos -= bl[cur].size;
 37         cur++;
 38     }
 39     bl[cur].num[pos - 1] = v;
 40     bl[cur].maxn = 0;
 41     for ( int i = 0; i < bl[cur].size; i++ )
 42     {
 43         bl[cur].maxn = max( bl[cur].maxn, bl[cur].num[i] );
 44     }
 45 }
 46 
 47 int query( int l, int r )
 48 {
 49     int cur = 0, inc = r - l;
 50     while ( l > bl[cur].size )
 51     {
 52         l -= bl[cur].size;
 53         cur++;
 54     }
 55     int ncur = cur;
 56     r = l + inc;
 57     while ( r > bl[ncur].size )
 58     {
 59         r -= bl[ncur].size;
 60         ncur++;
 61     }
 62     int ans = 0;
 63     for ( int i = cur + 1; i <= ncur - 1; i++ )
 64     {
 65         ans = max( ans, bl[i].maxn );
 66     }
 67     if ( cur == ncur )
 68     {
 69         for ( int j = l - 1; j < r; j++ )
 70         {
 71             ans = max( ans, bl[cur].num[j] );
 72         }
 73     }
 74     else
 75     {
 76         for ( int j = l - 1; j < bl[cur].size; j++ )
 77         {
 78             ans = max( ans, bl[cur].num[j] );
 79         }
 80         for ( int j = 0; j < r; j++ )
 81         {
 82             ans = max( ans, bl[ncur].num[j] );
 83         }
 84     }
 85     return ans;
 86 }
 87 
 88 int main()
 89 {
 90     while ( scanf("%d%d", &n, &m) != EOF )
 91     {
 92         tot = 0;
 93         bl[tot].init();
 94         int ps = sqrt((double)n);
 95         for ( int i = 0; i < n; i++ )
 96         {
 97             int tmp;
 98             scanf("%d", &tmp);
 99             if ( bl[tot].size == ps )
100             {
101                 tot++;
102                 bl[tot].init();
103             }
104             bl[tot].push(tmp);
105         }
106         char op[2];
107         int a, b;
108         while ( m-- )
109         {
110             scanf("%s%d%d", op, &a, &b);
111             if ( op[0] == 'Q' )
112             {
113                 printf("%d
", query( a, b ));
114             }
115             else
116             {
117                 update( a, b );
118             }
119         }
120     }
121     return 0;
122 }

对于这个题操作种类很少,可以写成二维数组的形式,看起来更简洁。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <cmath>
 5 using namespace std;
 6 
 7 const int M = 550;
 8 int b[M][M];
 9 int maxn[M];
10 int n, q;
11 int ps;
12 
13 int max( int a, int b )
14 {
15     return a > b ? a : b;
16 }
17 
18 void setv( int i, int j, int v )
19 {
20     b[i][j] = v;
21     maxn[i] = max( maxn[i], b[i][j] );
22 }
23 
24 int query( int l, int r )
25 {
26     int cur = l / ps, ncur = r / ps;
27     l = l % ps, r = r % ps;
28     int ret = -1;
29     for ( int i = cur + 1; i <= ncur - 1; i++ )
30     {
31         ret = max( ret, maxn[i] );
32     }
33     if ( cur != ncur )
34     {
35         for ( int j = l; j < ps; j++ )
36         {
37             ret = max( ret, b[cur][j] );
38         }
39         for ( int j = 0; j <= r; j++ )
40         {
41             ret = max( ret, b[ncur][j] );
42         }
43     }
44     else
45     {
46         for ( int j = l; j <= r; j++ )
47         {
48             ret = max( ret, b[cur][j] );
49         }
50     }
51     return ret;
52 }
53 
54 void update( int pos, int val )
55 {
56     int i = pos / ps, j = pos % ps;
57     b[i][j] = val;
58     maxn[i] = -1;
59     for ( int k = 0; k < ps && i * ps + k < n; k++ )
60     {
61         maxn[i] = max( maxn[i], b[i][k] );
62     }
63 }
64 
65 int main ()
66 {
67     ps = 500;
68     while ( scanf("%d%d", &n, &q) != EOF )
69     {
70         memset( maxn, -1, sizeof(maxn) );
71         for ( int i = 0; i < n; i++ )
72         {
73             int tmp; scanf("%d", &tmp);
74             setv( i / ps, i % ps, tmp );
75         }
76         char op[2];
77         int a, b;
78         while ( q-- )
79         {
80             scanf("%s%d%d", op, &a, &b);
81             if ( op[0] == 'Q' )
82             {
83                 a--; b--;
84                 printf("%d
", query( a, b ));
85             }
86             else
87             {
88                 a--;
89                 update( a, b );
90             }
91         }
92     }
93     return 0;
94 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4471049.html