题意 : 三种操作 , 一种操作往队列中加入一个 key val 键值对 , 第二种操作是输出 val 最高的key 并删除掉 , 第三种操作是输出 val 最低的key 并删除掉 , 如果队列为空,输出0
思路 : 做法很多拉 , 比如可以用map就直接水了 。用splay的话 , 我是直接把最大值和最小值splay到keyTree的位置,然后求出来删掉
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 100005
#define ls(x) (ch[x][0])
#define rs(x) (ch[x][1])
#define INF 0x3f3f3f3f
#define keyNode ( ch[ch[root][1]][0] )
struct Splay{
int tot ;
int top ;
int s[MAXN] ;
int ch[MAXN][2] ;
int pre[MAXN] ;
int sz[MAXN] ;
int val[MAXN] ;
int key[MAXN] ;
int root ;
void Rotate( int x , int op ){
int y = pre[x] ;
push_down( y ) ;
push_down( x ) ;
if( pre[y] )
ch[pre[y]][rs(pre[y])==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 ;
push_up( y ) ;
}
void splay( int x , int goal ){
push_down( x ) ;
while( pre[x] != goal ) {
int y = pre[x] ;
if( pre[y] == goal ) {
Rotate( x , rs(y) == x ) ;
}else{
int op = rs(y) == x ;
if( ch[pre[y]][op] == y ) {
Rotate( y , op ) ;
Rotate( x , op ) ;
}else{
Rotate( x , op ) ;
Rotate( x , op ^ 1 ) ;
}
}
}
push_up(x) ;
if( goal == 0 ) root = x ;
}
void RotateTo( int k , int goal ){
int x = root ;
push_down( x ) ;
while( k != sz[ls(x)] ) {
if( k < sz[ls(x)] ) {
x = ls(x) ;
}else{
k -= sz[ls(x)] + 1 ;
x = rs(x) ;
}
push_down(x) ;
}
splay( x , goal ) ;
}
void push_up( int x ){
sz[x] = 1 + sz[ls(x)] + sz[rs(x)] ;
}
void push_down( int x ){}
void del( int x ){
if( x ) {
s[top++] = x ;
del( ls(x) ) ;
del( rs(x) ) ;
}
}
void erase( int x ){
int fa = pre[x] ;
ch[fa][ rs(fa) == x ] = 0 ;
del( x ) ;
push_up(fa) ;
}
void debug( int x ){
if( x ) {
printf( "root = %d key = %d val = %d pre = %d lson = %d rson = %d sz = %d \n" , x , key[x] , val[x] , pre[x] , ls(x) , rs(x) , sz[x] ) ;
debug( ls(x) ) ;
debug( rs(x) ) ;
}
}
void makenode( int &x , int fa , int k , int v ){
if( top )
x = s[--top] ;
else
x = tot ++ ;
pre[x] = fa ;
key[x] = k ;
val[x] = v ;
ls(x) = rs(x) = 0 ;
sz[x] = 1 ;
}
void init(){
tot = 0 ;
top = 0 ;
makenode( root , 0 , 0 , 0 ) ;
sz[root] = 0 ;
makenode( root , 0 , 0 , -INF ) ;
makenode( rs(root) , root , 0 , INF ) ;
//sz[root] ++ ;
push_up(root) ;
}
void insert( int k , int v ){
int x = root ;
while( ch[x][v>val[x]] ) {
x = ch[x][v>val[x]] ;
}
makenode( ch[x][v>val[x]] , x , k , v ) ;
splay( ch[x][v>val[x]] , 0 ) ;
}
int size(){
return sz[root] - 2 ;
}
int get_min(){
int ans ;
if( size() == 0 ) return 0 ;
RotateTo( 0 , 0 ) ;
RotateTo( 2 , root ) ;
ans = key[keyNode] ;
erase( keyNode ) ;
push_up( root ) ;
return ans ;
}
int get_max(){
int ans = 0 ;
int ss = size() ;
if( ss == 0 ) return 0 ;
RotateTo( ss - 1 , 0 ) ;
RotateTo( ss + 1 , root ) ;
ans = key[keyNode] ;
erase( keyNode ) ;
push_up( root ) ;
return ans ;
}
}s;
int main(){
s.init() ;
//s.debug(s.root) ;
int op ;
while( scanf( "%d" , &op ) && op ) {
if( op == 1 ) {
int k , v ;
scanf( "%d%d" , &k, &v) ;
s.insert( k , v ) ;
}else if( op == 2 ) {
printf( "%d\n" , s.get_max() ) ;
} else{
printf( "%d\n" , s.get_min() ) ;
}
//s.debug(s.root) ;
}
return 0 ;
}