静态模板
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#define N 1000010
using namespace std;
class Node
{
public:
int f;
int l;
int r;
int vk;
int vp;
};
class Splay
{
public:
Node S[N];
int cur_id;
int root;
Splay()
{
cur_id = root = -1;
}
void R_rotate( int &x );
void L_rotate( int &x );
void splay ( int &x );
void insert_node( int vk, int vp );
int find_node( int vk, int vp, int T );
int find_min_node( int p );
int find_max_node( int p );
void copy_node( int p );
void init_node( int p );
void del_min_node( int p );
void del_max_node( int p );
};
void Splay::R_rotate( int &x )
{
if( S[x].f == -1 ) return ;
int y = S[x].f , z = S[y].f;
S[y].l = S[x].r;
S[x].r = y;
if( S[y].l != -1 ) S[S[y].l].f = y;
S[y].f = x;
S[x].f = z;
if( z!=-1 )
{
if( S[z].l == y ) S[z].l = x;
else S[z].r = x;
}
}
void Splay::L_rotate( int &x )
{
if( S[x].f == -1 ) return ;
int y = S[x].f, z = S[y].f;
S[y].r = S[x].l;
S[x].l = y;
if( S[y].r != -1 ) S[ S[y].r ].f = y;
S[y].f = x;
S[x].f = z;
if( z!=-1 )
{
if( S[z].l == y ) S[z].l = x;
else S[z].r = x;
}
}
void Splay::splay( int &x )
{
while( S[x].f != -1 )
{
int y = S[x].f, z = S[y].f;
if( z == -1 )
{
if( S[y].l == x ) R_rotate( x );
else L_rotate( x );
}
else
{
if( S[z].l == y && S[y].l == x )
{
R_rotate( y );
R_rotate( x );
}
else if( S[z].r == y && S[y].r == x )
{
L_rotate( y );
L_rotate( x );
}
else if( S[z].l == y && S[y].r == x )
{
L_rotate( x );
R_rotate( x );
}
else
{
R_rotate( x );
L_rotate( x );
}
}
}
root = x;
S[x].f = -1;
}
void Splay::init_node( int p )
{
S[p].f = S[p].vk = S[p].l = S[p].r = S[p].vp = -1;
}
int Splay::find_node( int vk, int vp, int T )
{
if( vp > S[T].vp && S[T].r!=-1 ) return find_node( vk,vp,S[T].r );
else if( vp < S[T].vp && S[T].l!=-1 ) return find_node(vk,vp,S[T].l);
else return T;
}
void Splay::insert_node( int vk, int vp )
{
int q = ++ cur_id;
init_node(q);
S[q].vk = vk;
S[q].vp = vp;
if( root == -1 ) root = 0;
else
{
int p = find_node( vk, vp , root );
S[q].f = p;
if( S[p].vp < vp ) S[p].r = q;
else S[p].l = q;
splay(q);
}
}
void Splay::copy_node( int p )
{
if( p == cur_id )
{
init_node(p);
if( cur_id >= 0) cur_id --;
return ;
}
if( root == cur_id && root != -1 ) root = p;
S[p].f = S[cur_id].f;
S[p].l = S[cur_id].l;
S[p].r = S[cur_id].r;
S[p].vk = S[cur_id].vk;
S[p].vp = S[cur_id].vp;
if( S[p].l != -1 ) S[ S[p].l ].f = p;
if( S[p].r != -1 ) S[ S[p].r ].f = p;
if( S[p].f !=-1 )
{
if( S[ S[p].f ].l == cur_id ) S[ S[p].f ].l = p;
else S[ S[p].f ].r = p;
}
if( cur_id >=0 ) cur_id --;
}
int Splay::find_min_node( int p )
{
if( root == -1 ) return -1;
if( S[p].l == -1 ) return p;
else return find_min_node ( S[p].l );
}
int Splay::find_max_node( int p )
{
if( root == -1 ) return -1;
if( S[p].r == -1 ) return p;
else return find_max_node( S[p].r );
}
void Splay::del_min_node( int p )
{
if( root == -1 ) return ;
int y = S[p].f, x = S[p].r;
if( y == -1 )
{
if( x != -1 ) S[x].f = -1;
root = x;
}
else
{
S[y].l = x;
if( x != -1 ) S[x].f = y;
}
copy_node(p);
}
void Splay::del_max_node( int p )
{
if( root == -1 ) return ;
int y = S[p].f, x = S[p].l;
if( y == -1 )
{
if( x!=-1 ) S[x].f = -1;
root = x;
}
else
{
S[y].r = x;
if( x != -1 ) S[x].f = y;
}
if( S[p].l != -1 ) S[ S[p].l ].f = y;
if( S[p].r != -1 ) S[ S[p].r ].f = y;
if( S[p].f !=-1 )
{
if( S[ S[p].f ].l == p ) S[ S[p].f ].l = x;
else S[ S[p].f ].r = x;
}
copy_node(p);
}
Splay SP;
int main()
{
for( int k,p,q,t; scanf("%d",&t),t; )
{
if( t == 1 )
{
scanf("%d%d",&k,&p);
SP.insert_node(k,p);
}
else if( 3 == t )
{
q = SP.find_min_node(SP.root);
if( q == -1 )
{
printf("0\n");
continue;
}
printf("%d\n",SP.S[q].vk);
SP.del_min_node(q);
}
else
{
q = SP.find_max_node(SP.root);
if( q == -1 )
{
printf("0\n");
continue;
}
printf("%d\n",SP.S[q].vk);
SP.del_max_node(q);
}
}
return 0;
}