这题是给定你一个区间,求里面的第K大的数;
这里用到划分树:
#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; }