树剖模板

树链剖分

无权值树剖

Code
struct tree_chain {
    int n, root;
    vector<int> fa, son, dep, top, sz;
    tree_chain(const vector<vector<int>> &adj, int _n, int _root) : n(_n), root(_root), fa(_n), son(_n, -1), dep(_n), top(_n), sz(_n) { dfs1(adj, root, -1, 1), dfs2(adj, root, root); }
    void dfs1(const vector<vector<int>> &adj, int now, int fath, int depth) {
        dep[now] = depth, fa[now] = fath, sz[now] = 1;
        int max_son = -1;
        for (auto v : adj[now]) {
            if (v == fath) continue;
            dfs1(adj, v, now, depth + 1), sz[now] += sz[v];
            if (sz[v] > max_son) son[now] = v, max_son = sz[v];
        }
    }
    void dfs2(const vector<vector<int>> &adj, int now, int top_id) {
        top[now] = top_id;
        if (son[now] == -1) return;
        dfs2(adj, son[now], top_id);
        for (auto v : adj[now])
            if (v != fa[now] and v != son[now]) dfs2(adj, v, v);
    }
    int lca(int u, int v) {
        while (top[u] != top[v]) dep[top[u]] >= dep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
        return dep[u] < dep[v] ? u : v;
    }
    int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
    /*
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        do something... dfn[top[x]],dfn[x]
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    do something... dfn[x],dfn[y]
    */
};  // the idx of begin is 0;

标准点权树剖

Code
template<typename T>
struct tree_chain {
    int n, root;
    vector<int> dfn, fa, son, dep, top, sz;
    vector<T> val;
    tree_chain(const vector<vector<int>>& adj, const vector<T>& old, int _root) : root(_root) {
        n = static_cast<int>(old.size());
        dfn.resize(n), fa.resize(n), son.assign(n, -1);
        dep.resize(n), top.resize(n), sz.resize(n), val.resize(n);
        dfs1(adj, root, -1, 1), dfs2(adj, old, root, root);
    }
    void dfs1(const vector<vector<int>>& adj, int now, int fath, int depth) {
        dep[now] = depth, fa[now] = fath, sz[now] = 1;
        int max_son = -1;
        for (auto v : adj[now]) {
            if (v == fath) continue;
            dfs1(adj, v, now, depth + 1), sz[now] += sz[v];  // this position can solve edge value
            if (sz[v] > max_son) son[now] = v, max_son = sz[v];
        }
    }
    void dfs2(const vector<vector<int>>& adj, const vector<T>& old, int now, int top_id) {
        static int tot = -1;
        dfn[now] = ++tot, val[tot] = old[now], top[now] = top_id;
        if (son[now] == -1) return;
        dfs2(adj, old, son[now], top_id);
        for (auto v : adj[now])
            if (v != fa[now] and v != son[now]) dfs2(adj, old, v, v);
    }
    int lca(int u, int v) {
        while (top[u] != top[v]) dep[top[u]] >= dep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
        return dep[u] < dep[v] ? u : v;
    }
    int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
    /*
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        do something... dfn[top[x]],dfn[x]
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    do something... dfn[x],dfn[y]
    */
};  // the idx of begin is 0  ,notice use dfn when?

从标号1开始的树剖

Code
template <typename T>
struct tree_chain {
    int n, root;
    vector<int> dfn, fa, son, dep, top, sz;
    vector<T> val;
    tree_chain(const vector<vector<int>>& adj, const vector<T>& old, int _root) : root(_root) {
        n = static_cast<int>(old.size());
        dfn.resize(n), fa.resize(n), son.resize(n);
        dep.resize(n), top.resize(n), sz.resize(n), val.resize(n);
        dfs1(adj, root, 0, 1), dfs2(adj, old, root, root);
    }
    void dfs1(const vector<vector<int>>& adj, int now, int fath, int depth) {
        dep[now] = depth, fa[now] = fath, sz[now] = 1;
        int max_son = -1;
        for (auto v : adj[now]) {
            if (v == fath) continue;
            dfs1(adj, v, now, depth + 1), sz[now] += sz[v];  // this position can solve edge value
            if (sz[v] > max_son) son[now] = v, max_son = sz[v];
        }
    }
    void dfs2(const vector<vector<int>>& adj, const vector<T>& old, int now, int top_id) {
        static int tot = 0;
        dfn[now] = ++tot, val[tot] = old[now], top[now] = top_id;
        if (son[now] == 0) return;
        dfs2(adj, old, son[now], top_id);
        for (auto v : adj[now])
            if (v != fa[now] and v != son[now]) dfs2(adj, old, v, v);
    }
    int lca(int u, int v) {
        while (top[u] != top[v]) dep[top[u]] >= dep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
        return dep[u] < dep[v] ? u : v;
    }
    int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
    /*
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        do something... dfn[top[x]],dfn[x]
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    do something... dfn[x],dfn[y]
    */
};  // the idx of begin is 1

边权转点权

Tips: 边权赋值在该边更深的一点上

Code
template <typename T>
struct tree_chain {
    int n, root;
    vector<int> dfn, fa, son, dep, top, sz;
    vector<T> val, old;
    tree_chain(const vector<vector<pair<int, T>>> &adj, int _n, int _root) : n(_n), root(_root) {
        dfn.resize(n), fa.resize(n), son.assign(n, -1), old.resize(n);
        dep.resize(n), top.resize(n), sz.resize(n), val.resize(n);
        dfs1(adj, root, -1, 1), dfs2(adj, root, root);
    }
    void dfs1(const vector<vector<pair<int, T>>> &adj, int now, int fath, int depth) {
        dep[now] = depth;
        fa[now] = fath;
        sz[now] = 1;
        int max_son = -1;
        for (auto [v, c] : adj[now]) {
            if (v == fath) continue;
            old[v] = c;                                      //边权转点权
            dfs1(adj, v, now, depth + 1), sz[now] += sz[v];  // this position can solve edge value
            if (sz[v] > max_son) son[now] = v, max_son = sz[v];
        }
    }
    void dfs2(const vector<vector<pair<int, T>>> &adj, int now, int top_id) {
        static int tot = -1;
        dfn[now] = ++tot, val[tot] = old[now], top[now] = top_id;
        if (son[now] == -1) return;
        dfs2(adj, son[now], top_id);
        for (auto [v, c] : adj[now])
            if (v != fa[now] and v != son[now]) dfs2(adj, v, v);
    }
    int lca(int u, int v) {
        while (top[u] != top[v]) dep[top[u]] >= dep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
        return dep[u] < dep[v] ? u : v;
    }
    int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
    /*
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        do something...
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    do something...
    */
};  // the idx of begin is 0  ,notice use dfn when?
posted @ 2022-08-08 11:46  Cattle_Horse  阅读(41)  评论(0编辑  收藏  举报