voidbuild(int &u, int l, int r){ u = ++tot; if (l == r) return; int mid = l + (r - l) / 2; build(ls[u], l, mid); build(rs[u], mid + 1, r); }
向主席树中加入元素
1 2 3 4 5 6 7 8 9 10
intmodify(int pre, int l, int r, int x){ int cur = ++tot; ls[cur] = ls[pre]; rs[cur] = rs[pre]; sum[cur] = sum[pre] + 1; if (l == r) return cur; int mid = l + (r - l) / 2; if (x <= mid) ls[cur] = modify(ls[cur], l, mid); else rs[cur] = modify(rs[cur], mid + 1, r); return cur; }
查询区间第k大,注意区间下标是从1开始
1 2 3 4 5 6 7 8
intquery(int u, int v, int l, int r, int k){ int ans = 0, x = sum[ls[v]] - sum[ls[u]]; int mid = l + (r - l) / 2; if (l == r) return l; if (k <= x) ans = query(ls[u], ls[v], l, mid, k); else ans = query(rs[u], rs[v], mid + 1, r, k - x); return ans; }