hdu 1908 Double Queue ( splay )

题意 : 三种操作 , 一种操作往队列中加入一个 key val 键值对 , 第二种操作是输出 val 最高的key 并删除掉 , 第三种操作是输出 val 最低的key 并删除掉 , 如果队列为空,输出0

思路 : 做法很多拉 , 比如可以用map就直接水了 。用splay的话 , 我是直接把最大值和最小值splay到keyTree的位置,然后求出来删掉

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

#define MAXN 100005
#define ls(x) (ch[x][0]) 
#define rs(x) (ch[x][1])
#define INF 0x3f3f3f3f
#define keyNode ( ch[ch[root][1]][0] ) 

struct Splay{
	int tot ;
	int top ;
	int s[MAXN] ;
	int ch[MAXN][2] ;
	int pre[MAXN] ;
	int sz[MAXN] ;
	int val[MAXN] ;
	int key[MAXN] ;
	int root ;

	void Rotate( int x , int op ){
		int y = pre[x] ;
		push_down( y ) ;
		push_down( x ) ;
		if( pre[y] ) 
			ch[pre[y]][rs(pre[y])==y] = x ;
		pre[x] = pre[y] ;
		pre[y] = x ;
		ch[y][op] = ch[x][op^1] ;
		if( ch[x][op^1] )
			pre[ch[x][op^1]] = y ;
		ch[x][op^1] = y ;
		push_up( y ) ;
	}
	void splay( int x , int goal ){
		push_down( x ) ;
		while( pre[x] != goal ) {
			int y = pre[x] ;
			if( pre[y] == goal ) {
				Rotate( x , rs(y) == x ) ;
			}else{
				int op = rs(y) == x ;
				if( ch[pre[y]][op] == y ) {
					Rotate( y , op ) ;
					Rotate( x , op ) ;
				}else{
					Rotate( x , op ) ;
					Rotate( x , op ^ 1 ) ;
				}
			}
		}
		push_up(x) ;
		if( goal == 0 ) root = x ;
	}
	void RotateTo( int k , int goal ){
		int x = root ;
		push_down( x ) ;
		while( k != sz[ls(x)] ) {
			if( k < sz[ls(x)] ) {
				x = ls(x) ;
			}else{
				k -= sz[ls(x)] + 1 ;
				x = rs(x) ;
			}
			push_down(x) ;
		}
		splay( x , goal ) ;
	}
	void push_up( int x ){
		sz[x] = 1 + sz[ls(x)] + sz[rs(x)] ;
	}
	void push_down( int x ){}
	void del( int x ){ 
		if( x ) {
			s[top++] = x ;
			del( ls(x) ) ;
			del( rs(x) ) ;
		}
	}
	void erase( int x ){
		int fa = pre[x] ;
		ch[fa][ rs(fa) == x ] = 0 ;
		del( x ) ;
		push_up(fa) ;
	}
	void debug( int x ){
		if( x ) {
			printf( "root = %d key = %d val  = %d pre = %d lson = %d rson = %d sz = %d \n" , x , key[x] , val[x] , pre[x] , ls(x) , rs(x) , sz[x] ) ;
			debug( ls(x) ) ;
			debug( rs(x) ) ;
		}
	}
	void makenode( int &x , int fa , int k , int v ){
		if( top )
			x = s[--top] ;
		else
			x = tot ++ ;
		pre[x] = fa ;
		key[x] = k ;
		val[x] = v ;
		ls(x) = rs(x) = 0 ;
		sz[x] = 1 ;
	}
	void init(){
		tot = 0 ;
		top = 0 ;
		makenode( root , 0 , 0 , 0 ) ;
		sz[root] = 0 ;
		makenode( root , 0 , 0 , -INF ) ;
		makenode( rs(root) , root , 0 , INF ) ;
		//sz[root] ++ ;
		push_up(root) ;
	}
	void insert( int k , int v ){ 
		int x = root ;
		while( ch[x][v>val[x]] ) {
			x = ch[x][v>val[x]] ;
		}
		makenode( ch[x][v>val[x]] , x , k , v ) ;
		splay( ch[x][v>val[x]] , 0 ) ;
	}
	int size(){
		return sz[root] - 2 ;
	}
	int get_min(){
		int ans ;
		if( size() == 0 ) return 0 ;
		RotateTo( 0 , 0 ) ;
		RotateTo( 2 , root ) ;
		ans = key[keyNode] ;
		erase( keyNode ) ;
		push_up( root ) ;
		return ans ;
	}
	int get_max(){
		int ans = 0 ;
		int ss = size() ;
		if( ss == 0 ) return 0 ;
		RotateTo( ss - 1 , 0 ) ;
		RotateTo( ss + 1 , root ) ;
		ans = key[keyNode] ;
		erase( keyNode ) ;
		push_up( root ) ;
		return ans ;
	}
}s;

int main(){
	s.init() ;
	//s.debug(s.root) ;
	int op ;
	while( scanf( "%d" , &op ) && op ) {
		if( op == 1 ) {
			int k , v ;
			scanf( "%d%d" , &k, &v) ;
			s.insert( k , v ) ;	
		}else if( op == 2 ) {
			printf( "%d\n" , s.get_max() ) ;
		} else{
			printf( "%d\n" , s.get_min() ) ;
		}
		//s.debug(s.root) ;
	}
	return 0 ;	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值