来源:POJ2104
划分树:
#include<iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,Qm;
const int MAXN = 100010;
int a[MAXN];
int tree[20][MAXN];
int tol[20][MAXN];
void build(int dep,int l,int r){
if(l == r) return ;
int mid = (l+r)>>1;
int same = mid-l+1;
for(int i=l;i<=r;i++) {
if(tree[dep][i] < a[mid]) same -- ;
}
int lpos = l;
int rpos = mid+1;
for(int i=l;i<=r;i++) {
if(tree[dep][i] < a[mid])
tree[dep+1][lpos++] = tree[dep][i];
else if(tree[dep][i] == a[mid] && same > 0){
tree[dep+1][lpos++] = tree[dep][i];
same -- ;
}
else
tree[dep+1][rpos++] = tree[dep][i];
tol[dep][i] = tol[dep][l-1]+lpos-l;
}
build(dep+1,l,mid);
build(dep+1,mid+1,r);
}
int query(int left,int right,int l,int r,int dep,int k){
// cout<<left<<" "<<right<<" "<<l<<" "<<r<<" "<<dep<<endl;
if(l == r) return tree[dep][l];
int mid = (left+right)>>1;
int cnt = tol[dep][r]-tol[dep][l-1];
if(cnt>=k){
int newl = left+tol[dep][l-1]-tol[dep][left-1];
int newr = newl+cnt-1;
return query(left,mid,newl,newr,dep+1,k);
}
else{
int newr = r+tol[dep][right]-tol[dep][r];
int newl = newr-(r-l-cnt);
return query(mid+1,right,newl,newr,dep+1,k-cnt);
}
}
int main(){
int l,r,k;
while(scanf("%d%d",&n,&Qm)==2){
memset(tree,0,sizeof tree);
for(int i=1;i<=n;i++) {
scanf("%d",a+i);
tree[0][i] = a[i];
}
sort(a+1,a+1+n);
build(0,1,n);
while(Qm--){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",query(1,n,l,r,0,k));
}
}
return 0;
}