poj 1442

两种操作, add:是向序列中加入一个数 , get是问第k小数是谁 , 可以用优先队列  , 也可以用treap , 还可以用线段树 。

线段树的做法为 , 先离散化 , 然后每次都往线段树中加入数 , 线段树相应的的点+1 , 然后可以二分找 。 思想很明显, 代码实现注意细节就行 , 不过我没去写了。这里只给出2种解法。

1:优先队列:两个优先队列, 一个最小优先 , 一个最大优先, 最大优先保存前i-1小的数 , 最小优先里面的数都比最大优先的大 ,那么每次询问第i小的数时 , 最小优先队列的第一个就是答案。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 #include<algorithm>
 6 
 7 const int N = 33333 ;
 8 
 9 using namespace std ;
10 
11 priority_queue<int , vector<int> , greater<int> >Min_Q ;
12 priority_queue<int , vector<int> , less<int> >Max_Q ;
13 
14 int val[N] , n , m ;
15 
16 int main()
17 {
18     while( scanf("%d%d" , &n , &m)==2 )
19     {
20            for( int i=1;i<=n;i++ )    scanf("%d" , &val[i]);
21            
22            while( !Min_Q.empty() ) Min_Q.pop() ;
23            while( !Max_Q.empty() ) Max_Q.pop() ;
24            
25            int p = 0 , rank = 1 , v ;
26            
27            for( int i=1;i<=m;i++ ){
28                 
29                 
30                                  scanf("%d" , &v) ;
31                                 
32                                  while( v>p ){
33                                            int num = val[++p] ;
34                                            
35                                            if( Max_Q.size()<rank-1 ) Max_Q.push( num ) ;
36                                            
37                                            else if( Max_Q.empty() || num>=Max_Q.top() ){
38                                                                Min_Q.push( num ) ;    
39                                            } 
40                                            else{
41                                                                Min_Q.push( Max_Q.top() );
42                                                                Max_Q.pop() ;
43                                                                Max_Q.push( num ) ;     
44                                            } 
45                                  }  
46                                  
47                                  printf("%d\n" , Min_Q.top()) ;
48                                  Max_Q.push( Min_Q.top() ) ;
49                                  Min_Q.pop() ;
50                                  rank++ ;
51            }  
52     }
53 }

2:treap, 模板题。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 
 7 const int N = 33333 ;
 8 
 9 using namespace std ;
10 
11 int val[N] , n , m , ans ;
12 
13 struct node{
14        node * ch[2] ;
15        int s , v , r ;
16        node(){
17               ch[0] = ch[1] = NULL ;
18               s = 1 ;       
19        }       
20        int cmp( int x )const{
21               if( x==v ) return -1 ;
22               return x<v?0:1 ;      
23        }
24        void maintain(){
25               s = 1 ;
26               if( ch[0]!=NULL ) s += ch[0]->s ;
27               if( ch[1]!=NULL ) s += ch[1]->s ;              
28        }
29 };
30 
31 void rotate( node * &o , int d ){
32      node * k = o->ch[d^1] ;
33      o->ch[d^1] = k->ch[d] ;
34      k->ch[d] = o ;
35      o->maintain() ; k->maintain() ;
36      o = k ;     
37 }
38 
39 bool find_x( node * o , int x ){
40      while( o!=NULL ){
41                      int d = o->cmp(x) ;
42                      if( d==-1 ) return true ;
43                      else o = o->ch[d] ;       
44      }
45      return false ;     
46 }
47 
48 void insert( node * &o , int x ){
49      if( o==NULL ){
50                  o = new node() ;
51                  o->v = x ; o->r = rand() ;
52                  return ;    
53      }     
54      
55      int d = o->cmp(x) ;
56      
57      if( d==-1 )       d = 1 ;
58      insert( o->ch[d] , x ) ;
59      if( o->ch[d]->r > o->r ) rotate( o , d^1 ) ;
60      o->maintain() ;
61 }
62 
63 bool findkth( node * o , int k ){
64      while( o!=NULL ){
65             if( o->s<k ) return false ;
66                     int l = o->ch[0]!=NULL ? o->ch[0]->s : 0 ;
67                     
68                     if( l+1==k ){
69                                ans = o->v ;
70                                return true ;    
71                     }       
72                     
73                     int d = l<k ;
74                     o = o->ch[d] ;
75                     k -= d*(l+1) ;
76      } 
77      return false ;
78 }
79 
80 int main()
81 {
82     while( scanf("%d%d" , &n , &m)==2 ){
83            for( int i=1;i<=n;i++ )    scanf("%d" , &val[i]) ;
84            
85            int p = 0 , rank = 1 , v;
86            
87            node * root = NULL ;
88            for( int i=1;i<=m;i++ ){
89                          scanf("%d" , &v);
90                          
91                          while( v>p ) insert( root , val[++p] ) ;//, cout<<p<<" "<<val[p]<<endl;
92                          
93                          if( findkth( root , rank++ )==true )
94                                       printf("%d\n" , ans);   
95            }       
96     }  
97 }

 

posted @ 2014-11-22 16:56  最爱风  阅读(161)  评论(0编辑  收藏  举报