zoukankan      html  css  js  c++  java
  • 树链剖分入门(浅谈树链剖分)

    树链剖分

    简介

    树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息。

    具体来说,将整棵树剖分为若干条链,使它组合成线性结构,然后用其他的数据结构维护信息;

    重边与轻边,重链与轻链

    在将一棵树分成若干条链时,我们最好不要盲目的分;

    有一种有效的分割方法就是,分成重链与轻链;

    重链:连续的重边组成一条链;

    轻链:连续的轻边组成一条链;

    那么怎么判断重边和轻边呢?

    我们定义

    重子节点 :表示其子节点中子树最大的子结点。如果有多个子树最大的子结点,取其一。如果没有子节点,就无重子节点;

    轻子节点 :表示剩余的所有子结点;

    那么重边和轻边就是

    重边:重子节点与它父节点相连的一条边;

    轻边:轻子节点与它父节点相连的一条边;

    如图

    代码实现

    首先我们给出一些;

    重要的数组

    $f[x]$        表示 $x$ 节点的父节点;

    $son[x]$   表示 $x$ 节点的重子节点;

    $dep[x]$   表示 $x$ 节点的深度;

    $size[x]$   表示 $x$ 节点的子树的节点个数;

    $top[x]$    表示 $x$ 节点所在这条链上的顶部节点;

    $id[x]$      表示 $x$ 节点的$DFN$序,也就是在线段树中的编号;

    $aa[x]$     表示 $x$ $DFN$序的节点权值;

    那么

    剖分代码

    inline void dfs(ll x,ll fa)//找重子节点 
    {
        size[x]=1;
        f[x]=fa;//记录父节点 
        for(re ll i=head[x];i;i=e[i].stb)
        {
            ll xx=e[i].to;
            if(xx==fa)//不能遍历到父节点 
                continue;
            dep[xx]=dep[x]+1;//统计深度 
            dfs(xx,x);
            size[x]+=size[xx];//统计子树节点数 
            if(!son[x]||size[xx]>size[son[x]])
                son[x]=xx;//找重子节点,也就是子树节点数最多的子节点 
        }
    }
    ll tot=0;//统计在线段树中的编号 
    inline void DFS(ll x,ll t)//t 表示这条链的顶部 
    {
        top[x]=t;//记录 
        id[x]=++tot;//记录在线段树中的编号 
        aa[tot]=w[x];//记录在线段树中的权值 
        if(!son[x])//如果没有重子节点 
            return;//返回 
        DFS(son[x],t);//先遍历重子节点 
        for(re ll i=head[x];i;i=e[i].stb)
        {
            ll xx=e[i].to;
            if(xx==f[x]||xx==son[x])//遍历轻子节点 
                continue;
            DFS(xx,xx);//每个开始的轻子节点的链顶就是自己 
        }
    }

    调用代码

        dfs(1,0);
        DFS(1,1);//1 所在链的顶部就是自己

     求LCA

    inline ll LCA(ll x,ll xx)
    {
        while(top[x]!=top[xx])
        {
            if(dep[top[x]]>dep[top[xx]])
                x=f[top[x]];
            else
                xx=f[top[xx]];
        }
        if(dep[x]<dep[xx])
            return x;
        else
            return xx;
    }

    线段树维护信息

    更新中。。。

  • 相关阅读:
    使用uibesizerpath + Cashaplayer画椭圆
    国庆节,回乡
    慎用单例
    终于碰到iOS对象集合深拷贝的坑
    Oracle 按表名导出数据
    代理模式(Proxy Pattern)
    享元模式(Flyweight Pattern)
    外观模式(Facade Pattern)
    组合模式
    装饰者模式
  • 原文地址:https://www.cnblogs.com/wzx-RS-STHN/p/13520384.html
Copyright © 2011-2022 走看看