题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4006
/*
AVL树的基本操作,插入、删除、查找,平均时间复杂度为:(logN)
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
const int NN = 1000010 ;
int N,K ;
struct Node{
int height ; //结点的高度
int cnt ; //子树中结点的个数
int value ; //结点的值
struct Node *left, *right ; //结点的左、右孩子
}q[NN] ; //AVL树的结点
typedef Node* pnode ;
pnode T ;
int cnt ;
/*
计算以T为Root的子树中共有多少个结点
*/
int calc_cnt( pnode T ){
if( T == NULL ) return 0 ;
else return T->cnt ;
}
/*
计算以T为Root的子树的高度,规定:空子树高度为-1,单结点高度为0 ;
*/
int calc_hei( pnode T ){
if( T == NULL ) return -1 ;
else return T->height ;
}
/*
对T子树进行一次“一字型”的一次左旋
应用于“左左”形式
*/
pnode singleRotateLeft( pnode T ){
pnode k = T->left ;
T->left = k->right ;
k->right = T ;
T->cnt = calc_cnt( T->left ) + calc_cnt( T->right ) + 1 ;
T->height = std::max( calc_hei( T->left ) , calc_hei( T->right ) ) + 1 ;
k->cnt = calc_cnt( k->left ) + calc_cnt( k->right ) + 1 ;
k->height = std::max( calc_hei( k->left ) , calc_hei( k->right ) ) + 1 ;
return k ;
}
/*
对T子树进行一次“一字型”的一次右旋
应用于“右右”形式
*/
pnode singleRotateRight( pnode T ){
pnode k = T->right ;
T->right = k->left ;
k->left = T ;
T->cnt = calc_cnt( T->left ) + calc_cnt( T->right ) + 1 ;
T->height = std::max( calc_hei( T->left ) , calc_hei( T->right ) ) + 1 ;
k->cnt = calc_cnt( k->left ) + calc_cnt( k->right ) + 1 ;
k->height = std::max( calc_hei( k->left ) , calc_hei( k->right ) ) + 1 ;
return k ;
}
/*
对T子树进行一次“之字型”的一次左双旋
适用于“右左”形式
*/
pnode doubleRotateLeft( pnode T ){
T->right = singleRotateLeft( T->right ) ;
return singleRotateRight( T ) ;
}
/*
对T子树进行一次“之字型”的一次右双旋
适用于“左右”形式
*/
pnode doubleRotateRight( pnode T ){
T->left = singleRotateRight( T->left ) ;
return singleRotateLeft( T ) ;
}
/*在T子树中插入一个关键字是v的结点*/
pnode insert( pnode T , int v ){
if( T==NULL ){
T = &q[cnt++] ;
T->value = v ;
T->cnt = 1 ;
T->height = 0 ;
T->left = T->right = NULL ;
return T ;
}
if( v <= T->value ){
T->left = insert( T->left , v ) ;
if( calc_hei(T->left) - calc_hei( T->right ) == 2 ){
if( v <= T->left->value ){
T = singleRotateLeft( T ) ;
}
else
T = doubleRotateRight( T ) ;
}
}
else{
T->right = insert( T->right , v ) ;
if( calc_hei( T->right ) - calc_hei(T->left) == 2 ){
if( v <= T->right->value ){
T = doubleRotateLeft( T ) ;
}
else
T = singleRotateRight( T ) ;
}
}
T->cnt = calc_cnt( T->left ) + calc_cnt( T->right ) + 1 ;
T->height = std::max( calc_hei(T->left) , calc_hei(T->right) ) + 1 ;
return T ;
}
pnode del( pnode T , int v ){
if( T==NULL ) return NULL ;
if( v < T->value ){
T->left = del( T->left , v ) ;
if( calc_hei( T->right ) - calc_hei( T->left) == 2 ){
if( T->right->left!=NULL && ( calc_hei(T->right->left) > calc_hei(T->right->right) ) ){
T = doubleRotateLeft( T ) ;
}
else
T = singleRotateRight( T ) ;
}
}
else if( v > T->value ){
T->right = del( T->right , v ) ;
if( calc_hei(T->left) - calc_hei(T->right) == 2 ){
if( T->left->right!=NULL && ( calc_hei(T->left->right) > calc_hei(T->left->left) ) ){
T = doubleRotateRight( T ) ;
}
else
T = singleRotateLeft( T ) ;
}
}
else{
if( T->left!=NULL && T->right!=NULL ){
pnode tmp = T->right ;
while( tmp->left != NULL ) tmp = tmp->left ;
T->value = tmp->value ;
T->cnt = tmp->cnt ;
T->right = del( T->right ,tmp->value ) ;
if( calc_hei(T->left) - calc_hei(T->right) == 2 ){
if( T->left->right!=NULL && ( calc_hei(T->left->right) > calc_hei(T->left->left) ) ){
T = doubleRotateRight( T ) ;
}
else
T = singleRotateLeft( T ) ;
}
}
else{
if( T->right == NULL ){
T = T->left ;
}
else
T = T->right ;
}
}
if( T == NULL ) return NULL ;
T->cnt = calc_cnt( T->left ) + calc_cnt( T->right ) + 1 ;
T->height = std::max( calc_hei(T->left) , calc_hei(T->right) ) + 1 ;
return T ;
}
int query( pnode T , int n ){
if( calc_cnt( T->left ) < n - 1 ) return query( T->right , n - calc_cnt(T->left) - 1) ;
else if( calc_cnt( T->left ) == n-1 ) return T->value ;
else return query( T->left , n ) ;
}
int main(){
char ch[5] ;
int a , tot ;
while( scanf("%d %d",&N,&K) == 2 ){
cnt = 0 ; T = NULL ; tot = 0 ;
for(int i=0;i<N;i++){
scanf("%s",ch);
if( ch[0] == 'I' ){
tot++ ;
scanf("%d",&a);
T = insert( T , a );
}
else if( ch[0] == 'D' ){
tot-- ;
scanf("%d",&a);
T = del( T , a ) ;
}
else{
printf("%d\n",query(T , tot - K + 1));
}
}
}
return 0 ;
}