题意 : 出纳员管理员工的信息 , 有几种命令
思路 : 对于 A 和 S 操作 , 其实不用更新整棵树的信息 , 而是只要对应的改变 min 就可以了 。
查找第 k 大的时候 , 应为工资可能会相同 , 所以要维护一个 cnt 域 , 光只有sz 域不够
删除的话 , 我是自己写了个 lower_bound , 然后把要删除的东西放到 keyTree 删掉
另外如果刚进来就是小于最低工资的 , 直接无视
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 100005
#define keyNode ( ch[ch[root][1]][0] )
#define ls(x) ( ch[x][0] )
#define rs(x) ( ch[x][1] )
#define wh(x,y) (rs(y)==x)
#define INF 0x3f3f3f3f
struct Splay{
int tot ;
int sz[MAXN] ;
int top ;
int val[MAXN] ;
int s[MAXN] ;
int pre[MAXN] ;
int ch[MAXN][2] ;
int cnt[MAXN] ;
int root ;
void Rotate( int x , int op ){
int y = pre[x] ;
pushdown(y) ;
pushdown(x) ;
if( pre[y] ) {
ch[pre[y]][wh(y,pre[y])] = x ;
}
pre[x] = pre[y] ;
pre[y] = x ;
ch[y][op] = ch[x][op^1] ;
if( ch[x][op^1] ) {
pre[ch[x][op^1]] = y ;
}
ch[x][op^1] = y ;
pushup(y) ;
}
void splay( int x , int goal ){
pushdown( x ) ;
while( pre[x] != goal ) {
int y = pre[x] ;
if( pre[y] == goal ) {
Rotate( x , wh( x , y ) ) ;
}else{
int op = wh( x , y ) ;
if( wh( y , pre[y] ) == op ) {
Rotate( y , op ) ;
Rotate( x , op ) ;
}else{
Rotate( x , op ) ;
Rotate( x , op^1 ) ;
}
}
}
pushup( x ) ;
if( goal == 0 ) root = x ;
}
void debug( int x ){
if( x ) {
printf( " x = %d lson = %d rson = %d pre = %d val = %d sz = %d cnt = %d \n" , x , ls(x) , rs(x) , pre[x] , val[x] , sz[x] , cnt[x] ) ;
debug( ls(x) ) ;
debug( rs(x) ) ;
}
}
void del( int x ){
if( x ) {
s[top++] = x ;
del(ls(x)) ;
del(rs(x)) ;
}
}
void erase( int x ){
if( x == 0 ) return ;
int fa = pre[x] ;
ch[fa][wh(x,fa)] = 0 ;
del( x ) ;
pushup( fa ) ;
}
void pushdown( int x ){}
void pushup( int x ){
sz[x] = sz[ls(x)] + sz[rs(x)] + cnt[x] ;
}
void makenode( int &x , int fa , int Sz , int v ){
if( top )
x = s[--top] ;
else
x = tot ++ ;
pre[x] = fa ;
sz[x] = Sz ;
cnt[x] = Sz ;
val[x] = v ;
ls(x) = rs(x) = 0 ;
}
void init(){
tot = 0 ;
top = 0 ;
makenode( root , 0 , 0 , 0 ) ;
makenode( root , 0 , 1 , -INF ) ;
makenode( rs(root) , root , 1 , INF ) ;
pushup( root ) ;
}
int size(){
return sz[root] - 2 ;
}
int findk( int k ){
int x = root ;
k = size() - k + 1 ;
if( k <= 0 ) return -1 ;
pushdown(x) ;
while( true ) {
if( sz[ls(x)] > k ) {
x = ls(x) ;
}else{
k -= sz[ls(x)] + cnt[x] ;
if( k < 0 ) break;
x = rs(x) ;
}
pushdown( x ) ;
}
return val[x] ;
}
void insert( int v ){
int x = root ;
pushdown( x ) ;
while( ch[x][v>val[x]] ) {
if( v == val[x] ) {
sz[x] ++ ;
cnt[x] ++ ;
splay( x , 0 ) ;
return ;
}
x = ch[x][v>val[x]] ;
pushdown( x ) ;
}
makenode( ch[x][v>val[x]] , x , 1 , v ) ;
splay( ch[x][v>val[x]] , 0 ) ;
}
int lower_bound( int key ) {
int x = root ;
pushdown(x) ;
int ans = -1 ;
while( x ) {
if( val[x] >= key ) {
ans = x ;
x = ls(x) ;
}else{
x = rs(x) ;
}
pushdown( x ) ;
}
return ans ;
}
void remove( int Min ){
// 找到第一个大于等于 Min 的数
int key = lower_bound( Min ) ;
splay( 1 , 0 ) ;
splay( key , root ) ;
erase( keyNode ) ;
pushup( root ) ;
}
}s ;
int main(){
int n , Min ;
while( scanf( "%d%d" , &n , &Min ) != EOF ) {
s.init() ;
//s.debug( s.root ) ;
int change = 0 ;
int left = 0 ;
for( int i = 1 ; i <= n ; i ++ ) {
char op[15] ;
scanf( "%s" , op ) ;
if( op[0] == 'I' ) {
int v ;
scanf( "%d" , &v ) ;
v -= change ;
if( v < Min ) continue ;
s.insert( v ) ;
}else if( op[0] == 'A' ) {
int k ; scanf( "%d" , &k ) ;
Min -= k ;
change += k ;
}else if( op[0] == 'S' ) {
int k ;
scanf( "%d" , &k ) ;
Min += k ;
change -= k ;
int tmp = s.size() ;
s.remove( Min ) ;
left += tmp - s.size() ;
}else{
int k ;
scanf( "%d" , &k ) ;
int ans = s.findk(k) ;
if( ans == -1 )
puts( "-1" ) ;
else
printf( "%d\n" , ans + change ) ;
}
//s.debug( s.root ) ;
}
printf( "%d\n" , left ) ;
}
return 0 ;
}