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\n", 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\n", query( a, b ));

85             }

86             else

87             {

88                 a--;

89                 update( a, b );

90             }

91         }

92     }

93     return 0;

94 }

 

你可能感兴趣的:(HDU)