poj 2104 K-th 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 left = l ,right = mid + 1, issame = mid - l + 1, same = 0;
     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 )
{
//    printf( "l=%d,r=%d,s=%d,t=%d,k=%d,dep=%d\n",l,r,a,b,k,deep);system("pause");
    if( l == r ) 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 );    
}
void print(){
    for( int i = 0 ; i < 5; i ++ ) //
    {
       for( int j = 1 ;j <=7 ;j ++ )
          printf( "%d ",node[i].val[j] );
        puts( "" );
    } //    
    
}
int main(  )
{
    int n,m,l,r,k;
    while( scanf( "%d %d",&n,&m )==2 )
    {
       for( int i = 1 ; i <= n ; i ++ )
       {
            scanf( "%d",&val[i] );
            node[0].val[i] = val[i];        
       }    
       sort( val + 1 , val + n + 1, cmp );
       build_tree( 1 , n , 0 );
//       print();
       for( int i = 0 ; i < m ; i ++ )
       {
            scanf( "%d %d %d",&l ,&r, &k );
            printf( "%d\n",Query( l , r , 0 , k , 1 , n ) );
       }
    }
    //system( "pause" );
    return 0;
}

 

posted @ 2012-07-19 23:28  wutaoKeen  阅读(147)  评论(0)    收藏  举报