代码
#include<iostream>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131
#define INF 0x3f3f3f3f
#define P pair<int,int>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-5;
const double pai=acos(-1.0);
const int N=2e5+10;
const int maxn=1e6+10;
const int mod=1000000007;
int n,q,m,cnt=0;
int a[N],b[N],root[N];
int sum[N<<5],L[N<<5],R[N<<5];
inline void build(int p,int l, int r)
{
p=++cnt,sum[p]=0;
if(l==r) return;
int mid=(l+r)>>1;
build(L[p],l,mid);
build(R[p],mid+1,r);
}
inline int update(int p,int l,int r,int pos)
{
int rt=++cnt;
L[rt]=L[p],R[rt]=R[p];sum[rt]=sum[p]+1;
if(l<r)
{
int mid=(l+r)>>1;
if(pos<=mid) L[rt]=update(L[p],l,mid,pos);
else R[rt]=update(R[p],mid+1,r,pos);
}
return rt;
}
inline int query(int u, int v, int l, int r, int k)
{
if(l>=r) return l;
int mid=(l+r)>>1,x=sum[L[v]]-sum[L[u]];
if(x>=k) return query(L[u],L[v],l,mid,k);
else return query(R[u],R[v],mid+1,r,k-x);
}
int main()
{
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
int len=unique(b+1,b+1+n)-b-1;
build(root[0],1,len);
for(int i=1;i<=n;i++)
{
int pos=lower_bound(b+1,b+1+len,a[i])-b;
root[i]=update(root[i-1],1,len,pos);
}
while(q--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
int pos=query(root[l-1],root[r],1,len,k);
printf("%d\n",b[pos]);
}
return 0;
}