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

    本文思路参考自何开大佬

    引子

    相信各位大佬一定会线段树这种非常实用的数据结构

    那么如果我们要维护一棵树上的链的权值的时候怎么办

    就比如说BZOJ1036树的统计这道题目

    可能诸位草率地想想线段树是可以口头AC的,But 这是在一棵树上,线段树支持的连续的区间操作

    在这棵树上,如果链的编号断断续续,那么我们的线段树就和暴力没有什么区别有一点点区别了

    概念

    所以这里就需要用到树链剖分,这种可以支持树上链操作的数据结构

    树链剖分有很多高大上的名词需要我们去记

    我们先定义一些概念东东

    size[u]表示以u为根的树的大小

    dep[u]表示u的深度(根的深度定为1)

    fa[u]表示u的爸爸(???)

    有了这些东东,我们开始定义真正的概念

    重儿子:u的所有儿子v中,size[v]最大的v称为u的重儿子

    轻儿子:u的所有儿子v中,不是重儿子的都被叫做轻儿子

    重边:u 连向它的重儿子的边称为重边

    轻边:u连向它的轻儿子的边称为轻边

    重链:组成这条链的所有的边都是重边

    轻链:组成这条连的所有边都是轻边

    一些小性质

    性质1:V为u的轻儿子,则必有size[V] <= size[u] / 2

    这个性质证明可以用到反证法

    如果存在V为轻儿子并且size[V] > size[u] / 2

    我们会发现如果一个节点成为重儿子的条件就是size[V] >= size[u] / (SonNumber[u])      //SonNumber[u]表示u的儿子的数目

    因为size[u] / 2 > size[u] / 3 > size[u] / 4 ………………………………

    而且size[V] 是不可能大于size[u]的

    所以,V为这时候只能为重儿子

    与假设不符

    证毕~~~~

    性质2:从根到某一节点的路径上,轻边的数量不超过O(log N),重链的数目不超过O(log N)

    这个我们也是可以证明的

    因为我们可以从性质1直接推得轻边的数量不超过O(log N)

    后来我们发现

    没存在一条轻边,就会出现两条重链

    所以重链的数量不超过O(log N)

    证毕~~~~

    操作

     核心操作其实有两个

    其中一个是找出所有的重儿子,因为重儿子找出来以后,重边也就找出来了

    第二个操作就是找出所有的重链

    那么来考虑修改和查询操作

     如果是修改的话,我们线段树凉拌加个蛋

    如果是查询的话,我们改一点点点点还是凉拌加个蛋

    我们如果可以将两个节点移到同一个重链上

    然后再进行线段树上的操作就行了

    对于在将一个节点移到同一个重链时,代码非常的好理解

    但是代码中有一个地方打错了

  • 相关阅读:
    POJ1475【推箱子】(双bfs)
    CH2101:【可达性统计】(拓扑排序+状态压缩)
    拓扑排序模板
    BZOJ 2288: 【POJ Challenge】生日礼物 优先队列+贪心+链表
    Play Framework 完整实现一个APP(六)
    Play Framework 完整实现一个APP(五)
    Play Framework 完整实现一个APP(四)
    Play Framework 完整实现一个APP(三)
    Play Framework 完整实现一个APP(二)
    Play Framework 完整实现一个APP(一)
  • 原文地址:https://www.cnblogs.com/TUncleWangT/p/7475699.html
Copyright © 2011-2022 走看看