模拟了快排的过程 得到的一棵树就是划分树了
静态查询区间第k大很方便
#include
#include
#include
#include
using namespace std;
#define maxn 111111
int tol[30][maxn],s[30][maxn];
int sorted[maxn];
void build(int dep,int l,int r){
if(l==r)return ;
int mid=((l+r)>>1);
int lpos=l,rpos=mid+1;
int same=(mid-l+1);
for(int i=l;i<=r;++i)
if(s[dep][i]0){
s[dep+1][lpos++] = s[dep][i] ;
same--;
}
else s[dep+1][rpos++] = s[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 dep,int l,int r,int L,int R,int k){
if(l == r)return s[dep][l];
int cnt=tol[dep][r]-tol[dep][l-1];
int mid=((L+R)>>1);
if(cnt>=k){
int newl=L+tol[dep][l-1]-tol[dep][L-1];
int newr=newl+cnt-1;
return query(dep+1,newl,newr,L,mid,k);
}
else{
int newr=r+(tol[dep][R]-tol[dep][r]);
int newl=newr-(r-l+1-cnt)+1;
return query(dep+1,newl,newr,mid+1,R,k-cnt);
}
}
int main(){
int t;scanf("%d",&t);
while(t--){
int n,m,a,b,k;
memset(tol,0,sizeof tol);
memset(s,0,sizeof s);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d",&s[0][i]);
sorted[i]=s[0][i];
}
sort(sorted+1,sorted+1+n);
build(0,1,n);
while(m--){
scanf("%d%d%d",&a,&b,&k);
printf("%d
",query(0,a,b,1,n,k));
}
}
return 0;
}