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