zoukankan      html  css  js  c++  java
  • 轻重链剖分/长短链剖分

    有时,我们要在树上进行操作。
    链操作比较容易维护。
    由于链每个点只有一个前驱和后继,所以可以直接使用数据结构维护。
    但是树上就难以维护。
    可以考虑把树分解成若干条链。这样子就把树的问题转化成了链的问题。
    定义一个点(x)的偏好儿子(p_x)
    除了叶子节点以外,每个节点(x)有且只有一个(p_x)
    定义链顶(tp)为每条链的顶端。
    从顶端一直沿着(p_x)走,能够走到链上的每一个节点。
    轻重链剖分主要用于处理树上的操作。
    确定(p)的方法是:按照每个节点的大小,(p_x)被设为(x)节点大小最大的节点(y)
    这样子,如果从一个点(x)跳到链顶,再跳到父亲,跳过的边都是轻重交替的。
    如果跳过一个轻边,则由于他的父亲有一个大小比当前点更大的儿子,所以每次跳过轻边,(x)的子树大小都(*=2)
    所以跳的时间复杂度是(log_2n)的。
    这个性质十分优秀,使得轻重链剖分可以嵌套其他数据结构。
    长短链剖分划分偏好儿子的方法是把子树深度最大的点作为偏好儿子。
    如果使用长短链剖分维护树上信息,
    设当前节点的最大深度为d,
    则由于他的当前点有一个深度比d更大的儿子,所以每次跳过轻边,(x)的子树大小至少(+=d+1),随后d++。
    这样子时间复杂度最坏情况是(O(sqrt{n}))的。
    所以用长短链剖分处理树上链信息问题十分不优秀。
    但是长短链剖分可以用于处理一些求子树和深度有关的信息。
    虽然这些信息可以使用线段树求出,但是长短链剖分的时间复杂度更低。
    如果维护一个子树深度=d的点,可以dp。
    (f_{x,i})表示x子树深度为i的点。
    显然枚举x的一个儿子y,(f_{x,i}+=f_{y,i-1})
    这样子时间复杂度是平方级的。
    但是如果我们先把当前节点继承偏好儿子的结果,再把非偏好儿子的结果加在当前儿子上。
    则时间复杂度是所有长链的长度和,即(O(n))

    轻重链剖分例题:
    天天爱跑步
    树的统计
    打击目标
    人造情感(没做)
    NOI2014 购票(非正解)
    SDOI2017 树点涂色
    数星星
    border的四种求法
    [ZJOI2018]历史(忘了)
    [SDOI2017]切树游戏
    [LNOI2014]LCA
    保卫王国
    [WC2020]有根树
    loj 黄金矿工(没做)
    UOJ53
    CF757G
    长短链剖分例题:
    dominant indices
    树上的鼠(忘了)
    [POI2014]hotel
    重建计划
    希望(没做)

  • 相关阅读:
    ffmpeg mp3转ogg的命令
    四个很好的开源app项目
    iOS 开发者必不可少的 75 个工具
    几点iOS开发技巧
    100 Most Influential Books According to Stack Overflow
    iOS图形处理和性能(转)
    Objc的底层并发API(转)
    GCD CoreData 简化CoreData操作(转)
    微信扫一扫背后的秘密:基于运动估计的智能传图算法(转)
    Objective-C 的 API 设计(转)
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/13667604.html
Copyright © 2011-2022 走看看