UVa 12299 - RMQ with Shifts
题目链接:
线段树,点修改。
1 #include <cstdio> 2 #include <cctype> 3 #define lson l, m, rt << 1 4 #define rson m + 1, r, ( rt << 1 ) | 1 5 6 const int MAXN = 100010; 7 const int INF = 2147483645; 8 9 int tree[ MAXN << 2 ]; 10 11 int min( int a, int b ) 12 { 13 return a < b ? a : b; 14 } 15 16 void PushUP( int rt ) 17 { 18 tree[rt] = min( tree[rt << 1] , tree[ rt << 1 | 1 ] ); 19 return; 20 } 21 22 void build( int l, int r, int rt ) 23 { 24 if ( l == r ) 25 { 26 scanf( "%d", &tree[rt] ); 27 return; 28 } 29 int m = ( l + r ) >> 1; 30 build(lson); 31 build(rson); 32 PushUP(rt); 33 } 34 35 void update( int p, int e, int l, int r, int rt ) 36 { 37 if ( l == r ) 38 { 39 tree[rt] = e; 40 return; 41 } 42 int m = ( l + r ) >> 1; 43 if ( p <= m ) update( p, e, lson ); 44 else update( p, e, rson ); 45 PushUP(rt); 46 return; 47 } 48 49 void GetNum( int p, int &e, int l, int r, int rt ) 50 { 51 if ( l == r ) 52 { 53 e = tree[rt]; 54 return; 55 } 56 int m = ( l + r ) >> 1; 57 if ( p <= m ) GetNum( p, e, lson ); 58 else GetNum( p, e, rson ); 59 return; 60 } 61 62 int Query( int L, int R, int l, int r, int rt ) 63 { 64 if ( L <= l && R >= r ) 65 return tree[rt]; 66 67 int ret = INF; 68 int m = ( l + r ) >> 1; 69 if ( L <= m ) ret = min( ret, Query( L, R, lson ) ); 70 if ( R > m ) ret = min( ret, Query( L, R, rson ) ); 71 return ret; 72 } 73 74 int main() 75 { 76 int n, Q; 77 char order[50]; 78 int addr[50], number[50]; 79 while ( ~scanf( "%d%d", &n, &Q ) ) 80 { 81 build( 1, n, 1 ); 82 while ( Q-- ) 83 { 84 scanf( "%s", order ); 85 if ( order[0] == 'q' ) 86 { 87 int x, y; 88 sscanf( order, "query(%d,%d)", &x, &y ); 89 // printf("##%d %d\n", x, y); 90 printf( "%d\n", Query( x, y, 1, n, 1 ) ); 91 } 92 else 93 { 94 int cnt = 0; 95 for ( int i = 0; order[i]; ) 96 { 97 if ( isdigit( order[i] ) ) 98 { 99 int sum = 0; 100 while ( isdigit( order[i] ) ) 101 sum = sum * 10 + order[i++] - '0'; 102 addr[cnt++] = sum; 103 } 104 else ++i; 105 } 106 107 for ( int i = 0; i < cnt; ++i ) 108 { 109 // printf( "=%d ", addr[i] ); 110 GetNum( addr[i], number[i], 1, n, 1 ); 111 // printf( "@%d\n", number[i] ); 112 } 113 for ( int i = 0; i < cnt; ++i ) 114 { 115 if ( i == cnt - 1 ) update( addr[i], number[0], 1, n, 1 ); 116 else update( addr[i], number[i + 1], 1, n, 1 ); 117 } 118 } 119 } 120 } 121 return 0; 122 }