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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm>
using namespace std;
#define N 100010 #define LN 17
int cas; int n, m; int a[N], b[N], rt[N]; int uni_num; int sum[N * LN + 4 * N], ls[N * LN + 4 * N], rs[N * LN + 4 * N]; int cnt;
int newnode(int l, int r, int s) { cnt++; ls[cnt] = l; rs[cnt] = r; sum[cnt] = s; return cnt; }
void build(int l, int r, int &x) { x = newnode(0, 0, 0); if (l == r) return; int mid = (l + r) >> 1; build(l, mid, ls[x]); build(mid + 1, r, rs[x]); }
void update(int l, int r, int &x, int px, int val) { x = newnode(ls[px], rs[px], sum[px] + 1); if (l == r) return; int mid = (l + r) >> 1; if (val > mid ) update(mid + 1, r, rs[x], rs[px], val); else update(l, mid, ls[x], ls[px], val); }
int query(int l, int r, int y, int x, int k) { if (l == r) return l; int mid = (l + r) >> 1; int dt = sum[ls[y]] - sum[ls[x]]; if (dt < k) return query(mid + 1, r, rs[y], rs[x], k - dt); return query(l, mid, ls[y], ls[x], k); }
int main() { scanf("%d", &cas); while (cas--) { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i] = a[i]; } sort(b + 1, b + 1 + n); uni_num = unique(b + 1, b + 1 + n) - b - 1; for (int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + uni_num, a[i]) - b; cnt = 0; build(1, uni_num, rt[0]); for (int i = 1; i <= n; i++) update(1, uni_num, rt[i], rt[i - 1], a[i]); int s, t, k; while (m--) { scanf("%d%d%d", &s, &t, &k); printf("%d\n", b[query(1, uni_num, rt[t], rt[s - 1], k)]); } } return 0; }
|