#include <iostream> #include <cstdio> #include <algorithm> int const maxn = 200010; using namespace std; int a[maxn], b[maxn]; //第几个版本的根节点编号 int root[maxn << 5]; int lc[maxn << 5], rc[maxn << 5], sum[maxn << 5]; int sz;//节点个数 int n, m; int true_n; void build(int &rt, int l, int r) { rt = ++sz; if (l == r) return; int mid = (l + r) >> 1; build(lc[rt], l, mid); build(rc[rt], mid + 1, r); } int update(int id, int l, int r, int pos) { int _id = ++sz; lc[_id] = lc[id], rc[_id] = rc[id], sum[_id] = sum[id] + 1; if (l == r) return _id; int mid = (r + l) >> 1; if (pos <= mid) lc[_id] = update(lc[id], l, mid, pos); else rc[_id] = update(rc[id], mid + 1, r, pos); return _id; } int query(int p, int q, int l, int r, int k) { if (l == r) return l; int x = sum[lc[q]] - sum[lc[p]]; int mid = (l + r) >> 1; if (x >= k) return query(lc[p], lc[q], l, mid, k); else return query(rc[p], rc[q], mid + 1, r, k - x); } int main() { while (~scanf("%d %d", &n, &m)) { sz = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i] = a[i]; } sort(b + 1, b + n + 1); true_n = unique(b + 1, b + n + 1) - b - 1; build(root[0], 1, true_n); for (int i = 1; i <= n; i++) { int pos = lower_bound(b + 1, b + true_n + 1, a[i]) - b; root[i] = update(root[i - 1], 1, true_n, pos); } while (m--) { int l, r, k; scanf("%d %d %d", &l, &r, &k); cout << b[query(root[l - 1], root[r], 1, true_n, k)] << endl; } } return 0; }
来源:https://www.cnblogs.com/woxiaosade/p/11421889.html