HDU 2665 Kth number

这里要用到划分树求第K大数:

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
using namespace std;
class Node
{
public:
      int num[100024],val[100024];    
}node[20];
int val[100024]; 
bool cmp( int a, int b )
{
    return a <= b;    
}
void build_tree( int l , int r , int deep )
{
    if( l == r ) return;
    int mid = ( l + r )>>1;
    int issame = mid - l + 1,same = 0;
    int left = l ,right = mid + 1;
    for( int i = l ; i <= r ; i ++ )
         if( node[deep].val[i] < val[mid] ) issame --;    
    for( int i = l ; i <= r ; i++ )
    {
         node[deep].num[i] = node[deep].num[i-1];
         if( node[deep].val[i] < val[mid] ) 
         {
             node[deep].num[i] ++;
             node[deep + 1].val[left++] = node[deep].val[i];
         }
         else if( node[deep].val[i] > val[mid] ) 
                  node[deep+1].val[right++] = node[deep].val[i];
         else if( same < issame )
              {
                  same ++;
                  node[deep].num[i] ++;
                  node[deep + 1].val[left++] = node[deep].val[i];
              }    
              else node[deep+1].val[right++] = node[deep].val[i];
    }
    build_tree( l , mid ,deep + 1 );
    build_tree( mid + 1 ,r , deep + 1 );
    
}
int Query( int a , int b, int deep , int k , int l ,int r )
{
    if( a == b ) return node[deep].val[a];
    int mid = ( l + r ) >>1;
    int d = node[deep].num[b] - node[deep].num[a-1];
    int s = node[deep].num[a-1] - node[deep].num[l-1];
    int ss = node[deep].num[b] - node[deep].num[l-1];
    int rx = a - l + 1 - s,ry = b - l + 1 - ss;
    if( d >= k ) return Query( l + s , l + ss -1 , deep + 1, k , l ,mid );
    else return Query( mid + rx , mid + ry , deep + 1 , k - d , mid + 1 , r );    
}
int main(  )
{
    int n,m,T,l,r,k;
    while( scanf( "%d",&T )==1 )
    {
       while( T -- )
       {
            scanf( "%d %d",&n,&m );
            for( int i = 1 ; i <= n ; i ++ )
            {
                 scanf( "%d",&node[0].val[i] );
                 val[i] = node[0].val[i];    
            }
            sort( val + 1, val + n  + 1 , cmp );
            build_tree( 1 , n , 0 );
            for( int i =  0; i < m ; i ++ )
            {
                scanf( "%d %d %d",&l ,&r,&k );
                if( l > r ) swap( l , r );
                printf( "%d\n",Query( l , r  , 0 , k , 1 , n  ) );    
            }        
       }    
    } 
    //system( "pause" );
    return 0;
}

 

posted @ 2012-07-19 21:31  wutaoKeen  阅读(158)  评论(0)    收藏  举报