# BZOJ 1901: Zju2112 Dynamic Rankings( BIT 套 BST )

BIT 套 splay

其实也是不难...每个 BIT 的结点保存一颗 splay , 询问就二分答案然后判断rank...

---------------------------------------------------------------

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>

#define rep( i , n ) for( int i = 0 ; i < n ; ++i )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
#define lowbit( x ) ( ( x ) & ( -x ) )

using namespace std;

const int maxn = 10000 + 5;
const int maxnode = 5e6;
const int inf = 2e9;

int n , mn , mx;
int seq[ maxn ];

struct Node* null;

queue< Node* > Q;

struct Node {
Node *ch[ 2 ] , *p;
int v , s;
Node( int _ = inf ) : v( _ ) , s( 1 ) {
ch[ 0 ] = ch[ 1 ] = p = null;
}
inline bool d() {
return this == p -> ch[ 1 ];
}
inline void setc( Node* c , int d ) {
ch[ d ] = c;
c -> p = this;
}
inline void upd() {
s = ch[ 0 ] -> s + ch[ 1 ] -> s + 1;
}
void* operator new( size_t ) {
Node* t = Q.front(); Q.pop();
return t;
}
};

Node pool[ maxnode ];

struct SPLAY {
Node* root;
void rot( Node* t ) {
Node* p = t -> p;
int d = t -> d();
p -> p -> setc( t , p -> d() );
p -> setc( t -> ch[ d ^ 1 ] , d );
t -> setc( p , d ^ 1 );
p -> upd();
if( p == root )
root = t;
}
void splay( Node* t , Node* f = null ) {
for( Node* p = t -> p ; p != f ; p = t -> p ) {
if( p -> p != f )
p -> d() != t -> d() ? rot( t ) : rot( p );
rot( t );
}
t -> upd();
}
Node* select( int k ) {
for( Node* t = root ; ; ) {
int s = t -> ch[ 0 ] -> s;
if( k == s ) return t;
if( k > s )
k -= s + 1 , t = t -> ch[ 1 ];
else
t = t -> ch[ 0 ];
}
}
int rank( int v ) {
int ans = 0;
for( Node* t = root ; t != null ; )
if( t -> v < v )
ans += t -> ch[ 0 ] -> s + 1 , t = t -> ch[ 1 ];
else
t = t -> ch[ 0 ];
return ans;
}
void insert( int v ) {
int k = rank( v );
Node *L = select( k - 1 ) , *R = select( k );
splay( L ) , splay( R , L );
R -> setc( new Node( v ) , 0 );
R -> upd();
root -> upd();
}
void del( int v ) {
int k = rank( v );
Node *L = select( k - 1 ) , *R = select( k + 1 );
splay( L );
splay( R , L );
Q.push( R -> ch[ 0 ] );
R -> setc( null , 0 );
R -> upd();
L -> upd();
}
};

SPLAY h[ maxn ];

void init() {
rep( i , maxnode ) Q.push( pool + i );
null = new Node();
null -> s = 0;
Rep( i , n ) {
h[ i ].root = new Node();
h[ i ].root -> setc( new Node( -inf ) , 0 );
h[ i ].root -> upd();
}
}

inline void del( int x , int v ) {
for( ; x <= n ; x += lowbit( x ) )
h[ x ].del( v );
}

inline void insert( int x , int v ) {
for( ; x <= n ; x += lowbit( x ) )
h[ x ].insert( v );
}

inline int rank( int l , int r , int v ) {
int ans = 0;
for( l-- ; l ; l -= lowbit( l ) )
ans -= h[ l ].rank( v ) - 1;
for( ; r ; r -= lowbit( r ) )
ans += h[ r ].rank( v ) - 1;
return ans + 1;
}

int query( int l , int r , int k ) {
int L = mn , R = mx , ans;
while( L <= R ) {
int m = ( L + R ) >> 1;
if( rank( l , r , m ) > k )
R = m - 1;
else
L = ( ans = m ) + 1;
}
return ans;
}

void modify( int pos , int v ) {
del( pos , seq[ pos ] );
insert( pos , seq[ pos ] = v );
}

int main() {
freopen( "test.in" , "r" , stdin );
freopen( "test.out" , "w" , stdout );
int q;
cin >> n >> q;
init();
Rep( i , n ) {
scanf( "%d" , seq + i );
insert( i , seq[ i ] );
}
mn = mx = seq[ 1 ];
for( int i = 2 ; i <= n ; ++i ) {
mx = max( seq[ i ] , mx );
mn = min( seq[ i ] , mn );
}
char c;
while( q-- ) {
scanf( " %c" , &c );
if( c == 'Q' ) {
int l , r , k;
scanf( "%d%d%d" , &l , &r , &k );
int t = query( l , r , k ) , p = *min_element( seq + l , seq + r + 1 );
for( int i = l ; i <= r ; ++i )
if( seq[ i ] <= t && seq[ i ] > p )
p = seq[ i ];
printf( "%d\n" , p );
} else {
int pos , v;
scanf( "%d%d" , &pos , &v );
mn = min( v , mn );
mx = max( v , mx );
modify( pos , v );
}
}
return 0;
}

---------------------------------------------------------------

## 1901: Zju2112 Dynamic Rankings

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 5363  Solved: 2243
[Submit][Status][Discuss]

5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

3
6

## HINT

20%的数据中，m,n≤100; 40%的数据中，m,n≤1000; 100%的数据中，m,n≤10000。

## Source

posted @ 2015-07-06 22:05  JSZX11556  阅读(...)  评论(...编辑  收藏