模板
#include <bits/stdc++.h> using namespace std; const int M = 1e5+7; int _,n,q,a[M],ls[M]; int L[M*20],R[M*20],num[M*20],T[M],tot,pos;//L每个节点的左子树,R每个节点的右子树,T存所有的节点 void build(int l,int r,int &rt){ rt=++tot; num[rt]=0;//空树没有数字存在 if(l==r){ return ; } int mid=(l+r)>>1; build(l,mid,L[rt]); build(mid+1,r,R[rt]); } void update(int l,int r,int &rt,int prert){ rt=++tot; num[rt]=(num[prert]+1);//比上一颗树数字个数多1 if(l==r){ return ; } int mid=(l+r)>>1; if(pos<=mid){ R[rt]=R[prert];//只有更新左子树,右子树状态和上一颗树一样 update(l,mid,L[rt],L[prert]); } else{ L[rt]=L[prert];//只更新右子树,左子树状态和上一颗树一样 update(mid+1,r,R[rt],R[prert]); } } int query(int l,int r,int lrt,int rrt,int k){ if(l==r){ return l; } int mid=(l+r)>>1; int sum=num[L[rrt]]-num[L[lrt]];//第r棵树减去第l-1棵树就是当前查询区间的数字个数 if(sum>=k) return query(l,mid,L[lrt],L[rrt],k); else return query(mid+1,r,R[lrt],R[rrt],k-sum); } void solve(){ sort(ls+1,ls+n+1); int sz=unique(ls+1,ls+n+1)-ls-1;//去重离散化 build(1,sz,T[0]);//建空树 for(int i=1;i<=n;i++){ pos=lower_bound(ls+1,ls+sz+1,a[i])-ls; update(1,sz,T[i],T[i-1]); } while(q--){ int l,r,k,ans; scanf("%d%d%d",&l,&r,&k); printf("%d\n",ls[query(1,sz,T[l-1],T[r],k)]);//查询的区间的状态由第r棵树减第l-1棵树得到 } } int main(){ scanf("%d",&_); while(_--){ scanf("%d%d",&n,&q);tot=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]),ls[i]=a[i]; solve(); } return 0; }