询问一个区间查询第K大
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010
using namespace std;
void read(int& num){
char ch = getchar();int f = 1;
for(; ch < '!'; ch = getchar());
if(ch == '-'){
f = -1;
ch = getchar();
}
for(num = 0; ch > '!'; ch = getchar())
num = num * 10 + ch - 48;
num *= f;
}
int n, m;
int a[maxn], h[maxn];
#define maxm 5000010
int T[maxn], L[maxm], R[maxm], c[maxm];
int tot, cnt;
int build(int l, int r){
int root = tot ++;
if(l == r)return root;
int mid = l + r >> 1;
L[root] = build(l, mid);
R[root] = build(mid + 1, r);
return root;
}
int update(int root, int pos, int val){
int newroot = tot ++, tmp = newroot;
int l = 1, r = cnt;
c[newroot] = c[root] + val;
while(l < r){
int mid = l + r >> 1;
if(pos <= mid){
L[newroot] = tot ++;
R[newroot] = R[root];
newroot = L[newroot];
root = L[root];
r = mid;
}
else{
R[newroot] = tot ++;
L[newroot] = L[root];
newroot = R[newroot];
root = R[root];
l = mid + 1;
}
c[newroot] = c[root] + val;
}
return tmp;
}
int ask(int l_root, int r_root, int k){
int l = 1, r = cnt;
while(l < r){
int mid = l + r >> 1;
int t = c[L[r_root]] - c[L[l_root]];
if(k <= t){
l_root = L[l_root];
r_root = L[r_root];
r = mid;
}
else{
k -= t;
l_root = R[l_root];
r_root = R[r_root];
l = mid + 1;
}
}
return l;
}
int main(){
//freopen("kthnumber.in", "r", stdin);
//freopen("kthnumber.out", "w", stdout);
read(n), read(m);
for(int i = 1; i <= n; i ++){
read(a[i]);
h[i] = a[i];
}
sort(h + 1, h + 1 + n);
cnt = unique(h + 1, h + 1 + n) - h - 1;
T[0] = build(1, cnt);
for(int i = 1; i <= n; i ++){
int pos = lower_bound(h + 1, h + 1 + cnt, a[i]) - h;
T[i] = update(T[i - 1], pos, 1);
}
int u, v, w;
for(int i = 1; i <= m; i ++){
read(u), read(v), read(w);
printf("%d\n", h[ask(T[u - 1], T[v], w)]);
}
return 0;
}