• 树链剖分


    多日前的博客,放在草稿箱快发霉了,今日来填坑!!!

    老早前听了一位大佬的难题选讲(难车选开)介绍了一下树链剖分,感觉很妙妙,恰好大佬降得蛮详细的,不花多少时间就理解了

    在这里就来介绍一下树链剖分,巩固一下记忆。

    还记得最初听一群大佬在以前难题选讲的时候,就用树链剖分来讲题,结果必然是直接全程懵逼,那时我旁边的宋爷就发誓要学这玩意儿,结果一起看博客又有点懵,没坚持下来。倒是宋爷过了一段时间继续重拾树链剖分,250+行代码强行写出,弄得我心里痒痒的,于是就学呗。。。。

    【树链剖分???】

    树链剖分能实现什么呢,这是我第一个想到的问题,想必初学者也疑问过,下面列举一下模板能干什么:

    操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z

    操作2: 格式: 2 x y 表示求树从x到y结点最短路径上所有节点的值之和

    操作3: 格式: 3 x z 表示将以x为根节点的子树内所有节点值都加上z

    操作4: 格式: 4 x 表示求以x为根节点的子树内所有节点值之和

    操作5: 格式: x y 表示求x和y的LCA

    【基础姿势】

     

    1、重儿子:每个节点的子树最大的子节点(如图中标没有红点的节点)

    2、 轻儿子:除去重儿子的节点

    3、重链:以每个轻儿子为起点到重儿子,路径上除起点外都是重儿子(也可以是单个轻儿子  如1—>4—>9—>13—>14)

    4、轻链:除去重链以外的路径

    5、链顶:每条链的起点,一定是轻儿子

    6、树链剖分搜索顺序:优先深搜一个节点的重儿子,再搜其他儿子

    储存结构

    siz[v]  以v为根节点的子树的大小

    fa[v]  节点v的父节点

    son[v]  节点v的重儿子

    top[v]  节点v所在链的链顶

    dep[v]  节点v的深度

    【建树操作】

    1、dfs( )

    第一次dfs我们是按dfs序来操作,更新fa[v] dep[v] siz[v] son[v]

     1 int dfs(int now,int ff,int deep)
     2 {
     3     fa[now]=ff,dep[now]=deep,siz[now]=1;
     4     int ms=-1,maxx=-1;
     5     for(int i=head[now];i!=0;i=edge[i].next)
     6     {
     7         if(edge[i].to!=ff)
     8         {
     9             int gg=dfs(edge[i].to,now,deep+1);
    10             if(maxx<gg)
    11             { maxx=gg,ms=edge[i].to; }
    12             siz[now]+=gg;
    13         }
    14     }
    15     if(ms==-1) son[now]=now;
    16     else son[now]=ms;
    17     return siz[now];
    18 }

    1、dfs2( )

    第二次dfs我们是按树链剖分的顺序来操作,更新top[v]

     1 void dfs2(int now,int tt)
     2 {
     3     cnt++,ord[cnt]=now,idx[now]=cnt,top[now]=tt;
     4     if(son[now]==now) return;
     5     dfs2(son[now],tt);
     6     for(int i=head[now];i!=0;i=edge[i].next)
     7     {
     8         if(edge[i].to!=fa[now]&&edge[i].to!=son[now])
     9             dfs2(edge[i].to,edge[i].to);
    10     }
    11 }

    接下来我们可以开始学习基本操作了(其实觉得LCA更简单,更贴切模板)

    求LCA:点我查看

    树链剖分模板:点我查看

  • 相关阅读:
    hdu 1290 献给杭电五十周年校庆的礼物 (DP)
    hdu 3123 GCC (数学)
    hdu 1207 汉诺塔II (DP)
    hdu 1267 下沙的沙子有几粒? (DP)
    hdu 1249 三角形 (DP)
    hdu 2132 An easy problem (递推)
    hdu 2139 Calculate the formula (递推)
    hdu 1284 钱币兑换问题 (DP)
    hdu 4151 The Special Number (DP)
    hdu 1143 Tri Tiling (DP)
  • 原文地址:https://www.cnblogs.com/genius777/p/8719043.html
Copyright © 2020-2023  润新知