• 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 }
  • 相关阅读:
    DIV+CSS笔记(二)
    DIV+CSS笔记(一)
    HTML基础笔记
    面向对象—封装—重载
    面向对象—封装
    面向对象—封装—people
    面向对象—封装—三角形
    权限修饰符—1
    权限修饰符—2(Father、Son)
    权限修饰符—3
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4471049.html
Copyright © 2020-2023  润新知