POJ 1442 Black Box ( Treap )

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<cstdlib>
using namespace std;

#define inf 0x3f3f3f3f
#define eps 1e-8
#define LL long long
#define ULL unsigned long long
#define MP make_pair
#define mxn 300030

struct node {
	node *ch[2];
	int v, r, s;
	node( int v ): v( v ) {
		r = rand();
		ch[0] = ch[1] = NULL;
		s = 1;
	}
	int cmp( int x ) {
		if( v == x )
			return -1;
		return x < v ? 0 : 1;
	}
	void mt() {
		s = 1;
		if( ch[0] )
			s += ch[0] -> s;
		if( ch[1] )
			s += ch[1] -> s;
	}
};
void rt( node *&p, int d ) {
	node *k = p -> ch[d^1];
	p -> ch[d^1] = k -> ch[d];
	k -> ch[d] = p;
	p -> mt();
	k -> mt();
	p = k;
}
void insert( node *&p, int x ) {
	if( p == NULL ) {
		p = new node( x );
		return;
	}
	int d = x < p -> v ? 0 : 1;
	insert( p -> ch[d], x );
	if( p -> ch[d] -> r > p -> r )
		rt( p, d ^ 1 );
	p -> mt();
}
bool find( node *p, int x ) {
	while( p ) {
		int d = p -> cmp( x );
		if( d == -1 )
			return 1;
		p = p -> ch[d];
	}
	return 0;
}
void remove( node *&p, int x ) {
	int d = p -> cmp( x );
	if( d == -1 ) {
		if( p -> ch[1] && p -> ch[0] ) {
			int d2 = p -> ch[0] -> r > p -> ch[1] -> r ? 1 : 0;
			rt( p, d2 );
			remove( p -> ch[d2], x );
		}
		else {
			node *u = p;
			if( p -> ch[0] == NULL )
				p = p -> ch[1];
			else
				p = p -> ch[0];
			delete u;
		}
	}
    else
            remove( p -> ch[d], x );
	if( p )
		p -> mt();
}
int kth( node *p, int k ) {
	if( p == NULL || k <= 0 || k > p -> s )
		return 0;
	int s = p -> ch[0] == NULL ? 0 : p -> ch[0] -> s;
	if( k == s + 1 )
		return p -> v;
	if( k <= s )
		return kth( p -> ch[0], k );
	return kth( p -> ch[1], k - s - 1 );
}
int rk( node *p, int x ) {
	int R;
	if( p -> ch[0] == NULL )
		R = 0;
	else
		R = p -> ch[0] -> s;
	if( x == p -> v )
		return R + 1;
	if( x < p -> v )
		return rk( p -> ch[0], x );
	return R + 1 + rk( p -> ch[1], x );
}
int a[mxn], cnt[mxn];
int n, m;
int main() {
//	freopen( "test.txt", "r", stdin );
	while( scanf( "%d%d", &n, &m ) != EOF ) {
		memset( cnt, 0, sizeof( cnt ) );
		for( int i = 1; i <= n; ++i ) {
			scanf( "%d", &a[i] );
		}
		for( int i = 1; i <= m; ++i ) {
			int t;
			scanf( "%d", &t );
			cnt[t]++;
		}
		node *root = NULL;
		int kk = 0;
		for( int i = 1; i <= n; ++i ) {
			insert( root, a[i] );
			while( cnt[i] ) {
				cnt[i]--;
				kk++;
				printf( "%d\n", kth( root, kk ) );
			}
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值