| Time Limit: 20000MS | Memory Limit: 65536K | |
| Total Submissions: 40169 | Accepted: 13120 | |
| Case Time Limit: 2000MS | ||
Description
Input
Output
Sample Input
7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3
Sample Output
5 6 3
Hint
求第k大数,划分树的模板题
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
int a[100005] , a_sort[100005] ;
int sum[20][100005] ;
int tree[20][100005] ;
void build(int c,int l,int r) {
if( l == r ) return ;
int mid = (l+r)/2 , m = mid-l+1 ;
int pl = l , pr = mid + 1 , i ;
for(i = l ; i <= mid ; i++)
if( tree[c][i] < a_sort[mid] )
m-- ;
for(i = l ; i <= r ; i++) {
if( i == l ) sum[c][i] = 0 ;
else sum[c][i] = sum[c][i-1] ;
if( tree[c][i] == a_sort[mid] ) {
if( m ) {
m-- ;
tree[c+1][pl++] = tree[c][i] ;
sum[c][i]++ ;
}
else
tree[c+1][pr++] = tree[c][i] ;
}
else if( tree[c][i] < a_sort[mid] ) {
tree[c+1][pl++] = tree[c][i] ;
sum[c][i]++ ;
}
else
tree[c+1][pr++] = tree[c][i] ;
}
build(c+1,l,mid) ;
build(c+1,mid+1,r) ;
}
int query(int c,int l,int r,int ql,int qr,int k) {
int num1 , num2 ; //num1?[l,ql) num2?[ql,qr]
int mid = (l+r) / 2 ;
if( l == r ) return tree[c][l] ;
if( l == ql ) {
num1 = 0 ;
num2 = sum[c][qr] ;
}
else {
num1 = sum[c][ql-1] ;
num2 = sum[c][qr] - num1 ;
}
if( k <= num2 )
query(c+1,l,mid,l+num1,l+num1+num2-1,k) ;
else
query(c+1,mid+1,r,mid+1+(ql-l-num1),mid+1+(qr-l-num1-num2),k-num2);
}
int main() {
int n , m , l , r , k ;
int i , j ;
while( scanf("%d %d", &n, &m) != EOF ) {
for(i = 1 ; i <= n ; i++) {
scanf("%d", &a[i]) ;
tree[0][i] = a_sort[i] = a[i] ;
}
sort(a_sort+1,a_sort+n+1) ;
build(0,1,n) ;
while( m-- ) {
scanf("%d %d %d", &l, &r, &k) ;
printf("%d\n", query(0,1,n,l,r,k) ) ;
}
}
return 0 ;
}
原文:http://blog.csdn.net/winddreams/article/details/44858947