题目传送门
sol:主席树,模板题
PS:这题从第一次错误提交到成功AC隔了半年,然后从半懂到现在会用了又隔了将近一年。前几天回顾了主席树,补上代码。
- 主席树
#include "cstdio" #include "algorithm" using namespace std; const int MAXN = 1e5 + 5; struct Node { int lson, rson; int cnt; } tree[MAXN * 30]; int root[MAXN], tot; int a[MAXN], b[MAXN]; int build(int l, int r) { int i = ++tot; tree[i].cnt = 0; if (l != r) { int mid = l + r >> 1; tree[i].lson = build(l, mid); tree[i].rson = build(mid + 1, r); } return i; } int add(int pre, int l, int r, int index) { int i = ++tot; tree[i] = tree[pre]; tree[i].cnt++; if (l != r) { int mid = l + r >> 1; if (index <= mid) tree[i].lson = add(tree[pre].lson, l, mid, index); else tree[i].rson = add(tree[pre].rson, mid + 1, r, index); } return i; } int query(int ql, int qr, int l, int r, int index) { if (l == r) return l; int sum = tree[tree[qr].lson].cnt - tree[tree[ql].lson].cnt; int mid = l + r >> 1; if (sum >= index) return query(tree[ql].lson, tree[qr].lson, l, mid, index); else return query(tree[ql].rson, tree[qr].rson, mid + 1, r, index - sum); } int main() { int t, n, m, q; int l, r, index; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &q); tot = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i] = a[i]; } sort(b + 1, b + 1 + n); m = unique(b + 1, b + 1 + n) - b - 1; root[0] = build(1, m); for (int i = 1; i <= n; i++) { index = lower_bound(b + 1, b + 1 + m, a[i]) - b; root[i] = add(root[i - 1], 1, m, index); } while (q--) { scanf("%d%d%d", &l, &r, &index); printf("%d ", b[query(root[l - 1], root[r], 1, m, index)]); } } return 0; }