标准的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;
}