题意很明白 正解应该是维护一颗二叉查找树 但是那玩意太难写 所以就出现了民间解法
建一个小根堆 一个大根堆
保证小根堆里的数都比大根堆里的大
当大根堆里元素个数为K时 大根堆堆顶元素就是第K小的 (第K大类似)
当添加一个元素时如果它比大根堆堆顶的元素小说明它应该插入大根堆(保证小根堆里的数都比大根堆里的大)
反之加入小根堆
当我们差第K小的元素时 就保证大根堆里只有K个 取堆顶就好
这种做法据说可以水完 但我没有可能哪儿写残了
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#define FOR( x , y ) for( int p = x ; p <= y ; p ++ )
using namespace std ;
int n ;
struct X{
int dui[ 250005 ] , top ;
void put( int x ) {
dui[ ++ top ] = x ;
int now = top , next ;
while( now > 1 ) {
next = now >> 1 ;
if( dui[ next ] <= dui[ now ] ) break ;
swap( dui[ next ] , dui[ now ] ) ;
now = next ;
}
}
int get( ) {
int res = dui[ 1 ] , now = 1 , next ; dui[ 1 ] = dui[ top -- ] ;
while( now << 1 <= top ) {
next = now << 1 ;
if( dui[ next + 1 ] < dui[ next ] ) next ++ ;
if( dui[ now ] <= dui[ next ] ) break ;
swap( dui[ now ] , dui[ next ] ) ;
now = next ;
}
return res ;
}
} xd ;
struct D{
int dui[ 250005 ] , top ;
void put( int x ) {
dui[ ++ top ] = x ;
int now = top , next ;
while( now > 1 ) {
next = now >> 1 ;
if( dui[ next ] >= dui[ now ] ) break ;
swap( dui[ next ] , dui[ now ] ) ;
now = next ;
}
}
int get( ) {
int res = dui[ 1 ] , now = 1 , next ; dui[ 1 ] = dui[ top -- ] ;
while( now << 1 <= top ) {
next = now << 1 ;
if( dui[ next + 1 ] > dui[ next ] ) next ++ ;
if( dui[ now ] >= dui[ next ] ) break ;
swap( dui[ now ] , dui[ next ] ) ;
now = next ;
}
return res ;
}
} dd ;
int cx( ) {
if( dd . top == 0 ) return 0 ;
else return dd . dui[ 1 ] ;
}
int main( ) {
freopen( "problem1.in" , "r" , stdin ) ;
freopen( "problem1.out" , "w" , stdout ) ;
char a ; int b , ges = 0 ;
scanf( "%d" , &n ) ; getchar( ) ;
FOR( 1 , n ) {
scanf( "%c%d" , &a , &b ) ; getchar( ) ;
if( a == 'i' ) {
ges ++ ;
if( b <= cx( ) ) dd . put( b ) ;
else xd . put( b ) ;
}
else {
b = ges - b + 1 ;
while( dd . top < b ) dd . put( xd . get( ) ) ;
while( dd . top > b ) xd . put( dd . get( ) ) ;
cout << dd . dui[ 1 ] << endl ;
}
}
return 0 ;
}