主席树模板
模板题:洛谷3834。
注意:数组至少32倍。
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int maxn = 200010; inline int qread(){ register int ch = getchar(), x = 0, flag = 0; while(ch < '0' || ch > '9') {if(ch == '-') flag = 1; ch = getchar();} while(ch >= '0' && ch <= '9') x = 10 * x + ch - 48, ch = getchar(); return flag ? -x : x; } int sum[maxn << 5]; int size[maxn << 5]; int ls[maxn << 5]; int rs[maxn << 5]; int rt[maxn]; int data[maxn]; int pl[maxn]; int n, sz, cnt, m; void build(int &x, int l, int r){ x = ++cnt; sum[x] = 0; if(l == r) return ; int mid = (l + r) >> 1; build(ls[x], l, mid); build(rs[x], mid + 1, r); } void update(int &x, int l, int r, int last, int p){ x = ++cnt; ls[x] = ls[last]; rs[x] = rs[last]; sum[x] = sum[last] + 1; if(l == r) return ; int mid = (l + r) >> 1; if(p <= mid) update(ls[x], l, mid, ls[last], p); else update(rs[x], mid + 1, r, rs[last], p); } int query(int a, int b, int l, int r, int k){ if(l == r) return l; int t = sum[ls[b]] - sum[ls[a]], mid = (l + r) >> 1; if(k <= t) return query(ls[a], ls[b], l, mid, k); else return query(rs[a], rs[b], mid + 1, r, k - t); } int main(void){ n = qread(); m = qread(); for(int i = 1; i <= n; ++i) pl[i] = data[i] = qread(); sort(pl + 1, pl + n + 1); sz = unique(pl + 1, pl + n + 1) - (pl + 1); build(rt[0], 1, sz); for(int i = 1; i <= n; ++i) data[i] = lower_bound(pl + 1, pl + sz + 1, data[i]) - pl; for(int i = 1; i <= n; ++i) update(rt[i], 1, sz, rt[i - 1], data[i]); while(m--){ int x = qread(), y = qread(), k = qread(); printf("%d\n", pl[query(rt[x - 1], rt[y], 1, sz, k)]); } }