标准的SBT,其实可以用堆来做的……这题没有体现出SBT强大的Delete功能~
参考代码:
program poj3481;//By_Thispoet
const
maxn=1000005;
var
sum,m,p,q,root:longint;
left,right,size,key,num:array[0..maxn]of longint;
procedure left_rotate(var t:longint);
var k:longint;
begin
k:=right[t];
right[t]:=left[k];
left[k]:=t;
size[k]:=size[t];
size[t]:=size[left[t]]+size[right[t]]+1;
t:=k;
end;
procedure right_rotate(var t:longint);
var k:longint;
begin
k:=left[t];
left[t]:=right[k];
right[k]:=t;
size[k]:=size[t];
size[t]:=size[left[t]]+size[right[t]]+1;
t:=k;
end;
procedure maintain(var t:longint; flag : boolean);
begin
if not flag then begin
if size[left[left[t]]]>size[right[t]] then
right_rotate(t)
else if size[right[left[t]]]>size[right[t]] then begin
left_rotate(left[t]);
right_rotate(t);
end else exit;
end else begin
if size[right[right[t]]]>size[left[t]] then
left_rotate(t)
else if size[left[right[t]]]>size[left[t]] then begin
right_rotate(right[t]);
left_rotate(t);
end else exit;
end;
maintain(left[t],false);
maintain(right[t],true);
maintain(t,false);
maintain(t,true);
end;
procedure insert_num(var t,p,q:longint);
begin
if t=0 then begin
inc(sum);t:=sum;
key[t]:=q;num[t]:=p;size[t]:=1;
left[t]:=0;right[t]:=0;
exit;
end;
inc(size[t]);
if q<key[t] then insert_num(left[t],p,q) else
insert_num(right[t],p,q);
maintain(t,q>=key[t]);
end;
procedure get_min(var t:longint);
begin
if left[t]=0 then begin
dec(size[t]);
writeln(num[t]);
t:=right[t];
exit;
end;
dec(size[t]);
get_min(left[t]);
maintain(t,true);
end;
procedure get_max(var t:longint);
begin
if right[t]=0 then begin
dec(size[t]);
writeln(num[t]);
t:=left[t];
exit;
end;
dec(size[t]);
get_max(right[t]);
maintain(t,false);
end;
begin
read(m);
sum:=0;root:=0;
while m>0 do begin
if m=1 then begin
readln(p,q);
insert_num(root,p,q);
end else if m=2 then begin
readln;
get_max(root);
end else begin
readln;
get_min(root);
end;
read(m);
end;
end.
C++参考代码:
/*
Name :Poj3481
Author :Thispoet
Time :2011-11-20
*/
# include <iostream>
# include <cstdio>
using namespace std;
const int maxN=1000005;
int m, p, q, sum = 0, root = 0;
int ll[maxN];
int rr[maxN];
int key[maxN];
int num[maxN];
int size[maxN];
inline void ll_Rotate( int &t )
{
int k = rr[t] ;
rr[t] = ll[k] ;
ll[k] = t ;
size[k] = size[t] ;
size[t] = size[ll[t]] + size[rr[t]] + 1 ;
t = k;
}
inline void rr_Rotate( int &t )
{
int k = ll[t] ;
ll[t] = rr[k] ;
rr[k] = t ;
size[k] = size[t] ;
size[t] = size[ll[t]] + size[rr[t]] + 1;
t = k;
}
inline void Maintain( int &t , bool flag )
{
if ( ! flag ) {
if ( size[ll[ll[t]]] > size[rr[t]] ) rr_Rotate(t) ;
else if ( size[rr[ll[t]]] > size[rr[t]] ) {
ll_Rotate( ll[t] ) ;
rr_Rotate( t ) ;
} else return ;
} else {
if ( size[rr[rr[t]]] > size[ll[t]] ) ll_Rotate(t) ;
else if ( size[ll[rr[t]]] > size[ll[t]] ) {
rr_Rotate( rr[t] ) ;
ll_Rotate( t );
} else return;
}
Maintain( ll[t] , false ) ;
Maintain( rr[t] , true ) ;
Maintain( t , false ) ;
Maintain( t , true ) ;
}
inline void Insert( int &t , int p , int q )
{
if ( t == 0 ){
t = ++sum ;
key[t] = q ; num [t] = p ; size [t] = 1 ;
ll[t] = 0 ; rr[t] = 0 ; return ;
}
++size[t] ;
if ( q < key[t] ) Insert( ll[t] , p , q ) ;
else Insert( rr[t] , p , q );
Maintain( t , q >= key[t] ) ;
}
inline void Get_Max( int &t )
{
if ( rr[t] == 0 ) {
--size[t]; printf( "%d\n", num[t] );
t = ll[t] ; return ;
}
--size[t] ;
Get_Max( rr[t] ) ;
Maintain( t , false );
}
inline void Get_Min( int &t )
{
if (ll[t] == 0 ) {
--size[t] ; printf( "%d\n" , num[t] );
t = rr[t] ; return ;
}
--size[t];
Get_Min( ll[t] ) ;
Maintain( t , true );
}
int main()
{
scanf( "%d" , &m );
while (m != 0 ) {
if ( m == 1 ) {
scanf( "%d%d", &p , &q );
Insert( root , p , q );
} else if ( m == 2) Get_Max( root ) ;
else Get_Min( root ) ;
scanf( "%d", &m );
}
return 0;
}