这里要用到划分树求第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 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; }