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;

}

 

你可能感兴趣的:(number)