【POJ】1442 Black Box 静态第k大,treap

来源:互联网 发布:英雄联盟号淘宝封了 编辑:程序博客网 时间:2024/05/17 22:28

传送门:【POJ】1442 Black Box


题目分析:treap模板题。。。连remove都不用。。


代码如下:


#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std ;#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REV( i , a , b ) for ( int i = a ; i >= b ; -- i )#define CLR( a , x ) memset ( a , x , sizeof a )const int MAXN = 30005 ;struct Node {Node *ch[2] ;int r ;int v ;int s ;Node ( int v = 0 ) : v ( v ) {ch[0] = ch[1] = NULL ;r = rand () ;s = 1 ;}int cmp ( const int &x ) {return x == v ? -1 : ( x < v ? 0 : 1 ) ;}void maintain () {s = 1 ;if ( ch[0] != NULL )s += ch[0] -> s ;if ( ch[1] != NULL )s += ch[1] -> s ;}} *root ;struct Edge {int v , n ;Edge () {}Edge ( int v , int n ) : v ( v ) , n ( n ) {}} E[MAXN] ;int H[MAXN] , cntE ;int n , m ;int a[MAXN] ;int ask[MAXN] ;void rotate ( Node *&o , int d ) {Node *k = o -> ch[d ^ 1] ;o -> ch[d ^ 1] = k -> ch[d] ;k -> ch[d] = o ;o -> maintain () ;k -> maintain () ;o = k ;}void insert ( Node *&o , int x ) {if ( o == NULL )o = new Node ( x ) ;else {int d = x < o -> v ? 0 : 1 ;insert ( o -> ch[d] , x ) ;if ( o -> ch[d] -> r > o -> r )rotate ( o , d ^ 1 ) ;}o -> maintain () ;}int kth ( Node *o , int k ) {int s = o -> ch[0] != NULL ? o -> ch[0] -> s : 0 ;if ( k == s + 1 )return o -> v ;else if ( k <= s )return kth ( o -> ch[0] , k ) ;elsereturn kth ( o -> ch[1] , k - s - 1 ) ;}void remove_tree ( Node *&o ) {if ( o -> ch[0] != NULL )remove_tree ( o -> ch[0] ) ;if ( o -> ch[1] != NULL )remove_tree ( o -> ch[1] ) ;delete o ;o = NULL ;}void init () {cntE = 0 ;CLR ( H , -1 ) ;}void addedge ( int u , int v ) {E[cntE] = Edge ( v , H[u] ) ;H[u] = cntE ++ ;}void solve () {int x ;init () ;FOR ( i , 1 , n )scanf ( "%d" , &a[i] ) ;FOR ( i , 1 , m ) {scanf ( "%d" , &x ) ;addedge ( x , i ) ;}FOR ( i , 1 , n ) {insert ( root , a[i] ) ;for ( int j = H[i] ; ~j ; j = E[j].n ) {int k = E[j].v ;ask[k] = kth ( root , k ) ;}}FOR ( i , 1 , m )printf ( "%d\n" , ask[i] ) ;remove_tree ( root ) ;}int main () {while ( ~scanf ( "%d%d" , &n , &m ) )solve () ;return 0 ;}


0 0