zoukankan      html  css  js  c++  java
  • 树链剖分

    树链剖分的本质是把树上的节点映射到一条直线,且各不相同,其映射的方法能保证在对树中一条路径进行处理时,把路径上的点映射到直线上,得到不超过log(n)条线段。然后可以用线段树(或其他数据结构)来维护得到的直线,来达到降低时间花费的目的。

    class TreeLHCut {
        //Tree node index start from 1
    private:
        int n, cnt;
        int *dep, *father, *siz, *top, *son, *tid, *rnk, *base;
        vector<vector<int> > * T;
        int * w;
        SegmentTree st;
        void dfs1(int u, int fa, int d);
        void dfs2(int u, int tp);
    public:
        TreeLHCut(int n) : st(n) {
            dep = (int *)malloc((n << 1) * sizeof(int));
            father = (int *)malloc((n << 1) * sizeof(int));
            siz = (int *)malloc((n << 1) * sizeof(int));
            top = (int *)malloc((n << 1) * sizeof(int));
            son = (int *)malloc((n << 1) * sizeof(int));
            tid = (int *)malloc((n << 1) * sizeof(int));
            rnk = (int *)malloc((n << 1) * sizeof(int));
            base = (int *)malloc((n << 1) * sizeof(int));
        }
        void cut(vector<vector<int> > * Tree, int * weight, int size);
        int Query(int u);
        void Modify(int u, int v, int k);
    };
    void TreeLHCut::dfs1(int u, int fa, int d) {
        dep[u] = d;
        father[u] = fa;
        siz[u] = 1;
        son[u] = -1;
        for (int i = 0; i < (*T)[u].size(); i++) {
            int v = (*T)[u][i];
            if (v == fa) continue;
            dfs1(v, u, d + 1);
            siz[u] += siz[v];
            if (son[u] == -1 || siz[v] > siz[son[u]]) son[u] = v;
        }
    }
    void TreeLHCut::dfs2(int u, int tp) {
        top[u] = tp;
        tid[u] = ++cnt;
        rnk[tid[u]] = u;
        if (son[u] == -1) return;
        dfs2(son[u], tp);
        for (int i = 0; i < (*T)[u].size(); i++) {
            int v = (*T)[u][i];
            if (v != son[u] && v != father[u]) dfs2(v, v);
        }
    }
    void TreeLHCut::cut(vector<vector<int> > * Tree, int * weight, int size) {
        T = Tree, w = weight, n = size, cnt = 0;
        dfs1(1, -1, 0);
        dfs2(1, 1);
        for (int i = 1; i <= n; i++) base[i] = w[rnk[i]];
        st.Build(base, 1, n, 1);
    }
    int TreeLHCut::Query(int u) {
        return st.QuerySegment(1, n, 1, tid[u], tid[u]);
    }
    void TreeLHCut::Modify(int u, int v, int k) {
        while (top[u] != top[v]) {
            if (dep[top[u]] < dep[top[v]]) swap(u, v);
            st.Modify(1, n, 1, tid[top[u]], tid[u], k);
            u = father[top[u]];
        }
        if (tid[u] > tid[v]) swap(u, v);
        st.Modify(1, n, 1, tid[u], tid[v], k);
    }
    View Code
  • 相关阅读:
    实战,利用apache来做集群,实现负载均衡
    Paas
    mysql memcache
    JSP简单练习-定时刷新页面
    协定须要双工,可是绑定“WSHttpBinding”不支持它或者因配置不对而无法支持它
    ACM:图的BFS,走迷宫
    appium框架之bootstrap
    [JSP]JSP中include指令和include动作的差别
    cocos2d-x-3.1 win32程序-初识源代码(coco2d-x 学习笔记二)
    AT&amp;T汇编语言——简单实例及工具演示
  • 原文地址:https://www.cnblogs.com/dramstadt/p/8006151.html
Copyright © 2011-2022 走看看