标签:
经典的线段树题目,也可以用块状链表做。
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 }
标签:
原文地址:http://www.cnblogs.com/huoxiayu/p/4471049.html