线段树合并模板

template<class Node>
struct PersidentSegmentTree {
#define lc(u) tr[u].l
#define rc(u) tr[u].r
    const int n;
    int tot = 0;
    vector<Node> tr;
    vector<int> root;

    PersidentSegmentTree(): n(0) {}

    PersidentSegmentTree(int n_): n(n_) {
        int N = (n << 6) + 10;
        tr.reserve(N); root.reserve(N);
        tr.resize(N); root.resize(N);
    }

    PersidentSegmentTree(vector<int>& a): PersidentSegmentTree(a.size() - 1) {
        function<void(int&, int, int)> build = [&](int& now, int l, int r) {
            now = ++ tot;
            if (l == r) {
                return ;
            }
            int m = (l + r) >> 1;
            build(lc(now), l, m);
            build(rc(now), m + 1, r);
        };
        build(root[0], 1, n);
    }

    //上传
    void pushup(int u) {
        if (tr[lc(u)].Sum >= tr[rc(u)].Sum) {
            tr[u].Sum = tr[lc(u)].Sum;
            tr[u].pos = tr[lc(u)].pos;
        } else {
            tr[u].Sum = tr[rc(u)].Sum;
            tr[u].pos = tr[rc(u)].pos;
        }
    }

    //动态开点/更新树结点
    void insert(int& now, int l, int r, int pos, int w) {
        if (!now)
            now = ++ tot;

        if (l == r) {
            tr[now].Sum += w;
            tr[now].pos = pos;
            return;
        }

        int m = l + r >> 1;
        if (pos <= m)
            insert(lc(now), l, m, pos, w);
        else
            insert(rc(now), m + 1, r, pos, w);
        pushup(now);
    }

    //开新前缀树,last代表前缀,now代表新树根
    void insert(int& now, int last, int l, int r, int pos, int w) {
        now = ++ tot;
        tr[now] = tr[last];
        if (l == r) {
            return;
        }
        int m = l + r >> 1;
        if (pos <= m)
            insert(lc(now), lc(last), l, m, pos, w);
        else
            insert(rc(now), rc(last), m + 1, r, pos, w);
    }

    //单点
    int query(int now, int l, int r, int pos) {
        if (l == r) {
            return tr[now].Sum;
        }

        int m = l + r >> 1;
        if (pos <= m)
            return query(lc(now), l, m, pos);
        else
            return query(rc(now), m + 1, r, pos);
    }

    //区间查询 [u,v]->[root[l-1],root[r]]
    int query(int u, int v, int l, int r, int pos) {
        if (l == r) {
            return tr[u].Sum;
        }

        int m = l + r >> 1;
        if (pos <= m)
            return query(lc(u), lc(v), l, m, pos);
        else
            return query(rc(u), rc(v), m + 1, r, pos);
    }

    void merge(int &u, int v, int l, int r) {
        if (!u || !v) {
            u = u + v;
            return;
        }

        if (l == r) {
            tr[u].Sum += tr[v].Sum;
            return ;
        }

        int m = l + r >> 1;
        merge(lc(u), lc(v), l, m);
        merge(rc(u), rc(v), m + 1, r);
        pushup(u);
    }
};

struct Node {
    int l, r;
    int Sum = 0, pos = 0;
};
posted @ 2024-08-09 11:04  Ke_scholar  阅读(8)  评论(0编辑  收藏  举报