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;

}

 

你可能感兴趣的:(number)