首页 > 代码库 > poj 1442

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 }

 

poj 1442