搞得最凄惨的一个题了。。。
各种不AC,MLE,RE,TLE,WA什么都有。。
要注意节点要计重
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<queue> #include<map> #include<set> #include<cstdlib> using namespace std; #define inf 0x3f3f3f3f #define eps 1e-8 #define LL long long #define ULL unsigned long long #define MP make_pair #define ls i << 1 #define rs ls | 1 #define mxn 50040 struct node { node *ch[2]; int v, r, s, cnt; node() {} node( int v ): v( v ) { r = rand(); ch[0] = ch[1] = NULL; s = 1; cnt = 1; } int cmp( int x ) { if( x == v ) return -1; return x < v ? 0: 1; } void mt() { s = cnt; if( ch[0] ) s += ch[0] -> s; if( ch[1] ) s += ch[1] -> s; } }pool[900003]; int sz = 0; node *creat() { node *p = &pool[sz++]; p -> s = 1; p -> ch[0] = p -> ch[1] = NULL; p -> r = rand(); p -> cnt = 1; return p; } struct treap { node *root; treap() { root = NULL; } void rt( node *&p, int d ) { node *k = p -> ch[d^1]; p -> ch[d^1] = k -> ch[d]; k -> ch[d] = p; p -> mt(); k -> mt(); p = k; } void insert( node *&p, int x ) { if( p == NULL ) { p = creat(); p -> v = x; return; } int d = p -> cmp( x ); if( d == -1 ) { p -> cnt++; p -> s ++; return; } insert( p -> ch[d], x ); if( p -> ch[d] -> r > p -> r ) rt( p, d ^ 1 ); p -> mt(); } void remove( node *&p, int x ) { int d = p -> cmp( x ); if( d == -1 ) { if( p -> cnt > 1 ) { p -> cnt--, p -> s--; } else { if( p -> ch[0] && p -> ch[1] ) { int d2 = p -> ch[0] -> r > p -> ch[1] -> r? 1: 0; rt( p, d2 ); remove( p -> ch[d2], x ); } else if( p -> ch[0] == NULL ) p = p -> ch[1]; else p = p -> ch[0]; } } else remove( p -> ch[d], x ); if( p ) p -> mt(); } bool find( node *p, int x ) { if( p == NULL ) return 0; int d = p -> cmp( x ); if( d == -1 ) return 1; return find( p -> ch[d], x ); } int kth( node *p, int k ) { if( p == NULL || k <= 0 || k > p -> s ) return 0; int s = p -> ch[0] == NULL ? 0: p -> ch[0] -> s; if( k == s + 1 ) return p -> v; if( k <= s ) return kth( p -> ch[0], k ); return kth( p -> ch[1], k - s - 1 ); } int rk( node *p, int x ) { if( p == NULL ) return 0; int R; if( p -> ch[0] == NULL ) R = 0; else R = p -> ch[0] -> s; if( x == p -> v ) { return R + p -> cnt; } if( x < p -> v ) { return rk( p -> ch[0], x ); } return rk( p -> ch[1], x ) + R + p -> cnt; } }; int ll[mxn<<2], rr[mxn<<2], a[mxn]; treap T[mxn<<2]; void build( int l, int r, int i ) { ll[i] = l, rr[i] = r; T[i].root = NULL; if( l == r ) { T[i].insert( T[i].root, a[l] ); return; } int m = ( l + r ) >> 1; build( l, m, ls ); build( m + 1, r, rs ); for( int j = l; j <= r; ++j ) T[i].insert( T[i].root, a[j] ); } void update( int k, int x, int y, int i ) { T[i].remove( T[i].root, x ); T[i].insert( T[i].root, y ); if( ll[i] == rr[i] ) { return; } int m = ( ll[i] + rr[i] ) >> 1; if( k <= m ) { update( k, x, y, ls ); } else { update( k, x, y, rs ); } } int find( int l, int r, int k, int i ) { if( ll[i] == l && rr[i] == r ) { return T[i].rk( T[i].root, k ); } int m = ( ll[i] + rr[i] ) >> 1; if( r <= m ) return find( l, r, k, ls ); if( l > m ) return find( l, r, k, rs ); return find( l, m, k, ls ) + find( m + 1, r, k, rs ); } void init() { memset( T, 0, sizeof( T ) ); memset( pool, 0, sizeof( pool ) ); sz = 0; } int main() { // freopen( "test.txt", "r", stdin ); int cas; scanf( "%d", &cas ); while( cas-- ) { init(); int n, m; scanf( "%d%d", &n, &m ); for( int i = 1; i <= n; ++i ) scanf( "%d", &a[i] ); build( 1, n, 1 ); char type[5]; for( int i = 1; i <= m; ++i ) { scanf( "%s", type ); if( type[0] == 'C' ) { int k, t; scanf( "%d%d", &k, &t ); update( k, a[k], t, 1 ); a[k] = t; continue; } int l, r, k; scanf( "%d%d%d", &l, &r, &k ); int head, tail; head = 0, tail = inf; while( head < tail ) { int mid = ( head + tail ) >> 1; if( find( l, r, mid, 1 ) < k ) { head = mid + 1; } else tail = mid; } printf( "%d\n", head ); } } return 0; }