#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1e5+5; int N,M; int A[MAXN]; int has[MAXN]; int htot; int get(int x){ int tt = lower_bound(has,has+htot,x)-has; return tt+1; } int show(int x){ return has[x-1]; } struct Node{ int ls; int rs; int sum; }tree[MAXN*30]; int root[MAXN]; int tot; int Ed; int Build(int l,int r) { int rt = tot++; tree[rt].sum = 0; if(l == r) return rt; int m = (l+r) >>1; tree[rt].ls = Build(l,m); tree[rt].rs = Build(m+1,r); return rt; } int Update(int pos,int num,int l,int r,int pre) { int rt = tot++; tree[rt] = tree[pre]; tree[rt].sum += num; if(l == r) return rt; int m = (l+r) >>1; if(pos <= m) tree[rt].ls = Update(pos,num,l,m,tree[pre].ls); else tree[rt].rs = Update(pos,num,m+1,r,tree[pre].rs); return rt; } int Qans; void Query(int num,int l,int r,int rt1,int rt2) { if(l == r) { Qans = r; return; } int m = (l + r) >>1; int tt = tree[tree[rt2].ls].sum - tree[tree[rt1].ls].sum; if(tt >= num) Query(num,l,m,tree[rt1].ls,tree[rt2].ls); else Query(num-tt, m+1, r, tree[rt1].rs,tree[rt2].rs); } void Debug(int l,int r,int rt){ printf("%d %d %d ",l,r,tree[rt].sum); if(l == r) { return; } int m = (l+r) >>1; Debug(l,m,tree[rt].ls); Debug(m+1,r,tree[rt].rs); } int main(){ while(~scanf("%d %d",&N,&M)) { htot = 0; for(int i = 1; i <= N; ++i) { scanf("%d",&A[i]); has[htot ++] = A[i]; } sort(has,has+htot); htot = unique(has, has+htot) - has; Ed = htot; tot = 0; root[0] = Build(1,Ed); for(int i = 1; i <= N; ++i) { int tt = get(A[i]); root[i] = Update(tt, 1, 1, Ed, root[i-1]); } // Debug(1,Ed,root[5]); printf(" "); // for(int i = 1; i <= N; ++i) printf("%d ",root[i]); printf(" "); for(int i = 1; i <= M; ++i) { int a,b,c; scanf("%d %d %d",&a,&b,&c); Query(c,1,Ed,root[a-1],root[b]); printf("%d ",show(Qans) ); } } return 0; }