http://acm.hdu.edu.cn/showproblem.php?pid=2665
主席树,静态,区间第k小。
这篇博文讲的非常好。https://blog.csdn.net/williamsun0122/article/details/77871278
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
int T,n,m,a[maxn],tree[maxn],L[maxn*20],R[maxn*20],sum[maxn*20],tot;
void build(int& o,int l,int r)
{
o=++tot;
sum[o]=0;
if(l==r)return;
int m=(l+r)/2;
build(L[o],l,m);
build(R[o],m+1,r);
}
void update(int& o,int l,int r,int pre,int x)
{
o=++tot;
sum[o]=sum[pre]+1;
L[o]=L[pre];
R[o]=R[pre];
if(l==r)return;
int m=(l+r)/2;
if(x<=m)update(L[o],l,m,L[pre],x);
else update(R[o],m+1,r,R[pre],x);
}
int query(int s,int t,int l,int r,int k)
{
if(l==r)return l;
int m=(l+r)/2;
int res=sum[L[t]]-sum[L[s]];
if(k<=res)return query(L[s],L[t],l,m,k);
else return query(R[s],R[t],m+1,r,k-res);
}
int main()
{
//freopen("input.in","r",stdin);
cin>>T;
while(T--)
{
cin>>n>>m;
tot=0;
vector<int> v;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),v.push_back(a[i]);
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
int sz=v.size();
build(tree[0],1,sz);
for(int i=1;i<=n;i++)
{
update(tree[i],1,sz,tree[i-1],lower_bound(v.begin(),v.end(),a[i])-v.begin()+1);
}
for(int i=1;i<=m;i++)
{
int s,t,k;
scanf("%d%d%d",&s,&t,&k);
cout<<v[query(tree[s-1],tree[t],1,sz,k)-1]<<"\n";
}
}
}