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 ; }