静态主席树,用于查找区间内第k大的数字,空间复杂度4*n+nlog2(n),时间复杂度(n+q)log2(n)
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<ctime>
#include<algorithm>
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 1e18
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e5+10;
const int mod=1e4+7;
int tot=0;
int aa[maxn],a[maxn],L[maxn*21],R[maxn*21],sum[maxn*21],T[maxn];
void build(int l,int r,int &rt)
{
rt=++tot;
sum[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 pre,int x)
{
rt=++tot;
L[rt]=L[pre];
R[rt]=R[pre];
sum[rt]=sum[pre]+1;
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)update(l,mid,L[rt],L[pre],x);
else update(mid+1,r,R[rt],R[pre],x);
}
int query(int l,int r,int tl,int tr,int k)
{
if(l==r)return l;
int mid=(l+r)>>1;
int res=sum[ L[tr] ] - sum[ L[tl] ];
if(res>=k)query(l,mid,L[tl],L[tr],k);
else query(mid+1,r,R[tl],R[tr],k-res);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&aa[i]),a[i]=aa[i];
sort(a+1,a+1+n);
int num=unique(a+1,a+1+n)-a-1;
tot=0;
build(1,num,T[0]);
for(int i=1;i<=n;i++){
int x=lower_bound(a+1,a+1+num,aa[i])-a;
update(1,num,T[i],T[i-1],x);
}
while(m--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
int pos=query(1,num,T[l-1],T[r],k);
printf("%d\n",a[pos]);
}
}
return 0;
}