只过了前两个点。
#include <bits/stdc++.h>//喵内~
#define int long long
#define re register//喵内~
using namespace std;//喵内~
typedef long long ll;
typedef long double ld;
const int N = 3e5 + 5;//喵内~要填数字哟~
inline int read(){
int s = 0,f = 1;char c = getchar();
while (!isdigit(c)){if (c == '-')f = -1;c = getchar();}
while (isdigit(c)){s = (s<<3) + (s<<1) + (c ^ 48);c = getchar();}
return s * f;
}//喵内~
int n,m;
int a[N],bucket[N],len;
struct SegmentTree{
int cnt,root[N];
struct node{
int l,r,val;
}tree[N << 5];
int Newnode(){
return ++cnt;
}
void pushup(int rt){
tree[rt].val = tree[tree[rt].l].val + tree[tree[rt].r].val;
}
void build(int &rt,int l,int r){
if (!rt)
rt = Newnode();
tree[rt] = (node){0,0,0};
if (l == r){return;}
int mid = (l + r) >> 1;
build(tree[rt].l,l,mid);
build(tree[rt].r,mid+1,r);
}
void update(int pre,int &rt,int l,int r,int pos){
if (!rt)
rt = Newnode();
tree[rt].val = tree[pre].val + 1;
if (l == r){
return ;
}
int mid = (l + r) >> 1;
if (pos <= mid)
tree[rt].r = tree[pre].r,update(tree[pre].l,tree[rt].l,l,mid,pos);
if (pos > mid)
tree[rt].l = tree[pre].l,update(tree[pre].r,tree[rt].r,mid+1,r,pos);
//pushup(rt);
}
int query(int pre,int rt,int l,int r,int k){
if (l == r)
return l;
int v = tree[tree[rt].l].val - tree[tree[pre].l].val;
int mid = (l + r) >> 1;
if (k > v)
return query(tree[pre].r,tree[rt].r,mid+1,r,k - v);
else return query(tree[pre].l,tree[rt].l,l,mid,k);
}
}Tree;
signed main(){
n = read(); m = read();
for (int i=1;i<=n;i++){
a[i] = read();
bucket[i] = a[i];
}
sort(bucket+1,bucket+n+1);
len = unique(bucket+1,bucket+n+1) - bucket - 1;
Tree.build(Tree.root[0],1,len);
for (int i=1;i<=n;i++)
Tree.update(Tree.root[i-1],Tree.root[i],1,len,lower_bound(bucket+1,bucket+len+1,a[i]) - bucket);
sort(a+1,a+n+1);
for (int i=1;i<=m;i++){
int l,r,k;
l = read(); r = read(); k = read();
printf("%lld\n",a[Tree.query(Tree.root[l-1],Tree.root[r],1,len,k)]);
}
return 0;
}//喵内~
/*
*/