# ConanKIDの小窝

### 主席树 学习笔记

posted on 2021-11-06 13:00:52 | under 学习笔记 |

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int n, m, len;
int a[maxn], ind[maxn], rt[maxn];
struct PresidentTree {
#define mid (l + r >> 1)
int ls[maxn << 5], rs[maxn << 5], sum[maxn << 5];
int cnt;
int build(int l, int r) {
int k = ++cnt;
if (l == r) return k;
ls[k] = build(l, mid); rs[k] = build(mid + 1, r);
return k;
}
int update(int k, int l, int r, int val) {
int dir = ++cnt; ls[dir] = ls[k]; rs[dir] = rs[k]; sum[dir] = sum[k] + 1;
if (l == r) return dir;
if (val <= mid) ls[dir] = update(ls[k], l, mid, val);
else rs[dir] = update(rs[k], mid + 1, r, val);
return dir;
}
int query(int l, int r, int p, int q, int val) {
if (l == r) return l;
int x = sum[ls[q]] - sum[ls[p]];
if (val <= x) return query(l, mid, ls[p], ls[q], val);
else return query(mid + 1, r, rs[p], rs[q], val - x);
}
} t;
void discrete() {
memcpy(ind, a, sizeof(a));
sort(ind + 1, ind + 1 + n);
len = unique(ind + 1, ind + 1 + n) - ind - 1;
for (int i = 1; i <= n; i++)
a[i] = lower_bound(ind + 1, ind + 1 + len, a[i]) - ind;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
discrete();
t.build(1, len);
for (int i = 1; i <= n; i++)
rt[i] = t.update(rt[i - 1], 1, len, a[i]);
for (int i = 1; i <= m; i++) {
int l, r, k; cin >> l >> r >> k;
cout << ind[t.query(1, len, rt[l - 1], rt[r], k)] << endl;
}
return 0;
}