structnode { int lch, rch, sum; } tree[maxn * 40];
int a[maxn]; int b[maxn]; int root[maxn]; int tot;
/* [l ,r] 当前区间, rt 当前树节点编号 */ voidbuild(int l, int r, int& rt){ rt = tot++; tree[rt].sum = 0; if (l == r) { return; } int m = (l + r) >> 1; build(l, m, tree[rt].lch); build(m + 1, r, tree[rt].rch); }
/* [l, r] 当前区间, rt 当前树节点编号, pre 前一棵线段树的当前节点, c 更新的点 */ voidupdate(int l, int r, int& rt, int pre, int c){ rt = tot++; tree[rt] = tree[pre]; tree[rt].sum += 1; if (l == r) { return; } int m = (l + r) >> 1; if (c <= m) { update(l, m, tree[rt].lch, tree[pre].lch, c); } else { update(m + 1, r, tree[rt].rch, tree[pre].rch, c); } }
/* [l, r] 当前区间, rt 当前树节点编号, pre 前一棵线段树的当前节点, 第 k 小 */ intquery(int l, int r, int rt, int pre, int k){ if (l == r) { return l; } int m = (l + r) >> 1; int lnum = tree[tree[rt].lch].sum - tree[tree[pre].lch].sum; if (lnum >= k) { return query(l, m, tree[rt].lch, tree[pre].lch, k); } else { return query(m + 1, r, tree[rt].rch, tree[pre].rch, k - lnum); } }
intmain(){ int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i] = a[i]; } /* 离散化 */ sort(b + 1, b + n + 1); int num = unique(b + 1, b + n + 1) - (b + 1); build(1, num, root[0]); for (int i = 1; i <= n; i++) { int p = lower_bound(b + 1, b + num + 1, a[i]) - b; update(1, num, root[i], root[i - 1], p); } while (m--) { int l, r, k; scanf("%d%d%d", &l, &r, &k); int p = query(1, num, root[r], root[l - 1], k); printf("%d\n", b[p]); } return0; }