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