http://blog.csdn.net/libing923/article/details/9724631
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100001; //点的个数
const int M=18; //建树的深度
int arr[N],sorted[N],val[M][N],toleft[M][N];
void build(int l,int r,int d){
if(l==r)return;
int m=(l+r)>>1;
int same=m-l+1,i=l,j=m+1,k;
for(k=l;k<=r;k++)if(val[d][k]<sorted[m])same--;
for(k=l;k<=r;k++){
if(val[d][k]<sorted[m])val[d+1][i++]=val[d][k];
else if(val[d][k]==sorted[m]&&same>0){
val[d+1][i++]=val[d][k];
same--;
}else val[d+1][j++]=val[d][k];
toleft[d][k]=toleft[d][l-1]+i-l;
}
build(l,m,d+1);
build(m+1,r,d+1);
}
int query(int L,int R,int l,int r,int d,int k){
if(l==r)return val[d][l];
int m=(L+R)>>1;
int cnt=toleft[d][r]-toleft[d][l-1];
if(cnt>=k){
int nl=L+toleft[d][l-1]-toleft[d][L-1];
int nr=nl+cnt-1;
return query(L,m,nl,nr,d+1,k);
}else{
int nr=r+toleft[d][R]-toleft[d][r];
int nl=nr-(r-l-cnt);
return query(m+1,R,nl,nr,d+1,k-cnt);
}
}
int main(){
int T,n,m,s,t,k,i;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m); //n个数,m个询问
for(i=1;i<=n;i++){
scanf("%d",&val[0][i]);
sorted[i]=val[0][i];
}
sort(sorted+1,sorted+n+1);
build(1,n,0); //建一个划分树
while(m--){
scanf("%d%d%d",&s,&t,&k);
printf("%d\n",query(1,n,s,t,0,k)); //询问s到t之间第k个数 的值
}
}
return 0;
}