1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include <cstdio> #include <algorithm> using namespace std; const int N = 200001; int n, m, a[N], nums[N], root[N], idx, l, r, k, len; struct Node { int l, r, cnt; } tr[N * 4 + N * 18]; int find(int x) { return lower_bound(nums + 1, nums + 1 + len, x) - nums; } int build(int l, int r) { int p = ++idx; if (l == r) return p; int mid = (l + r) >> 1; tr[p].l = build(l, mid), tr[p].r = build(mid + 1, r); return p; } int insert(int p, int l, int r, int x) { int q = ++idx; tr[q] = tr[p]; if (l == r) { ++tr[q].cnt; return q; } int mid = (l + r) >> 1; if (x <= mid) tr[q].l = insert(tr[p].l, l, mid, x); else tr[q].r = insert(tr[p].r, mid + 1, r, x); tr[q].cnt = tr[tr[q].l].cnt + tr[tr[q].r].cnt; return q; } int query(int q, int p, int l, int r, int k) { if (l == r) return r; int cnt = tr[tr[q].l].cnt - tr[tr[p].l].cnt, mid = (l + r) >> 1; if (k <= cnt) return query(tr[q].l, tr[p].l, l, mid, k); return query(tr[q].r, tr[p].r, mid + 1, r, k - cnt); } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); nums[i]= a[i]; } sort(nums + 1, nums + 1 + n); len = unique(nums + 1, nums + 1 + n) - nums - 1; root[0] = build(1, len + 1); for (int i = 1; i <= n; ++i) root[i] = insert(root[i - 1], 1, len, find(a[i])); while (m--) { scanf("%d%d%d", &l, &r, &k); printf("%d\n", nums[query(root[r], root[l - 1], 1, len, k)]); } return 0; }
|