可持久化线段树

Template

namespace Snb_tree {
    const int N = 2e6 + 100;
    struct node {
        int l, r;
        int s;
    };
    struct Snb_tree {
        int rt[N];
        int sz;
        node ts[N];
        int left, right;
        void init(int a, int b) {
            MEM(rt, 0);
            MEM(ts, 0);
            sz = 0;
            left = a, right = b;
        }
        void _add(int &root, int old_rt, int l, int r, int x) {
            root = ++ sz;
            ts[root].l = ts[root].r = 0;
            ts[root].s = ts[old_rt].s + 1;
            if (l == r) return;
            int mid = (l + r) / 2;
            if (x > mid) _add(ts[root].r, ts[old_rt].r, mid + 1, r, x), ts[root].l = ts[old_rt].l;
            else _add(ts[root].l, ts[old_rt].l, l, mid, x), ts[root].r = ts[old_rt].r;
        }
        void add(int i, int x) {
            _add(rt[i], rt[i - 1], left, right, x);
        }
        int _query(int rtl, int rtr, int l, int r, int k) {
            if (l == r) return l;
            int t = ts[ts[rtr].l].s - ts[ts[rtl].l].s;
            int mid = (l + r) / 2;
            if (k <= t) return _query(ts[rtl].l, ts[rtr].l, l, mid, k);
            else return _query(ts[rtl].r, ts[rtr].r, mid + 1, r, k - t);
        }
        int query(int l, int r, int k) {
            return _query(rt[l - 1], rt[r], left, right, k);
        }
    };
}
Snb_tree::Snb_tree g;

results matching ""

    No results matching ""