可持久化线段树
// 洛谷: https://www.luogu.org/problemnew/show/P3919
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6+500; #define lson rt->left #define rson rt->right struct nobe { int val; nobe *left; nobe *right; nobe () { val = 0; left = right = NULL; } }; int date[maxn]; nobe *head[maxn]; void build(int l, int r, nobe* rt) { if (l == r) { rt->val = date[l]; return ; } rt->left = new nobe(); rt->right = new nobe(); int m = (l + r) / 2; build(l, m, lson); build(m+1, r, rson); } int query(int l, int r, int id, nobe *rt) { if (l==id && r==id) return rt->val; int mid = (l + r) / 2; if (id <= mid) return query(l, mid, id, lson); return query(mid+1, r, id, rson); } void update(int l, int r, int id, int val, nobe *rt, nobe *nrt) { nrt->val = rt->val; nrt->left = lson; nrt->right = rson; if (l==id && r==id) { nrt->val = val; return ; } int mid = (l + r) / 2; if (id <= mid) { nrt->left = new nobe(); update(l, mid, id, val, lson, nrt->left); } else { nrt->right = new nobe(); update(mid+1, r, id, val, rson, nrt->right); } } int main() { // freopen("E:\\output.txt", "w", stdout); // freopen("E:\\input.txt", "r", stdin); int n, m, i, j; scanf("%d%d", &n, &m); for (i=1; i<=n; ++i) scanf("%d", date+i); head[0] = new nobe(); build(1, n, head[0]); int vs, op, id, val; for (i=1; i<=m; ++i) { scanf("%d%d%d", &vs, &op, &id); if (op == 1) { scanf("%d", &val); head[i] = new nobe(); update(1, n, id, val, head[vs], head[i]); } else if (op == 2) { head[i] = head[vs]; printf("%d\n", query(1, n, id, head[vs])); } } return 0; }
数组
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+10, LOG = 20; struct nobe { int lson; int rson; int sum; }te[maxn * LOG]; int head[maxn]; int tot; int date[maxn]; int tdate[maxn]; int build(int l, int r) { int rt = tot++; int mid = (l + r) / 2; if (l != r) { te[rt].lson = build(l, mid); te[rt].rson = build(mid+1, r); } return rt; } inline update(int pre, int l, int r, int x) { int rt = tot++, mid = (l + r) / 2; te[rt].lson = te[pre].lson; te[rt].rson = te[pre].rson, te[rt].sum = te[pre].sum + 1; if (l != r) { if (x <= mid) te[rt].lson = update(te[pre].lson, l, mid, x); else te[rt].rson = update(te[pre].rson, mid+1, r, x); } return rt; } inline int query(int u, int v, int l , int r, int k) { if (l == r) return l; int x = te[te[v].lson].sum - te[te[u].lson].sum, mid = (l + r) / 2; if (x >= k) return query(te[u].lson, te[v].lson, l, mid, k); else return query(te[u].rson, te[v].rson, mid+1, r, k-x); } int main() { int t, i, m; int n, q, x, y, z, p; scanf("%d", &t); while (t--) { tot = 1; memset(te, 0, sizeof(te)); memset(date, 0, sizeof(date)); memset(tdate, 0, sizeof(tdate)); scanf("%d%d", &n, &q); for (i=1; i<=n; ++i) { scanf("%d", date+i); tdate[i] = date[i]; } sort(tdate+1, tdate+n+1); int lst = tdate[1]; int m = 1; for (i=2; i<=n; ++i) { if (lst != tdate[i]) { lst = tdate[i]; tdate[++m] = tdate[i]; } } m = unique(tdate+1, tdate+n+1) - tdate - 1; head[0] = build(1, m); for (i=1; i<=n; ++i) { date[i] = lower_bound(tdate+1, tdate+m+1, date[i]) - tdate; head[i] = update(head[i-1], 1, m, date[i]); } while (q--) { scanf("%d%d%d", &x, &y, &z); p = query(head[x-1], head[y], 1, m, z); printf("%d\n", tdate[p]); } } return 0; }