• 虚树入门


    虚树入门

    标签: 虚树


    概念

    在处理某些问题时,不需要用到整棵树的信息,只需要某些点时,我们可以新建一棵虚树来放这些点与某些关键点。通常来说,构建的虚树中有这些点和这些点的lca。假如我们要将k个点与其lca构成一棵虚树,那么所需要的时间复杂度为O(klogk)。

    顺便提一下,这k个点和其所有的lca的点的个数和是小于2×k-1的,至于为什么的话,可以看构树的过程,每加入一个点最多只会多一个点。

    构建过程

    我们先对原树dfs一遍,得到原树的dfs序。
    然后我们把需要加入的点按照dfs序排序,这有什么好处呢,下文会提到。
    我们还需要维护一个栈,这个栈中存的是最后一个新加入的点的dfs链。(在这条链上,dfs序是递增的)
    现在新插入一个点v,假如栈顶的元素为u,现在有两种情况:

    1. lca(u,v)==u:
      • 我们就可以直接把v插入栈中,继续维护这条链;
    2. lca(u,v)!=u:
      • 首先lca(u,v)不可能等于v吧。(因为我们是按照dfs序依次加入的,这点很重要!)
      • 其次,再也没有新的点会插入在u的子树内了(因为我们是按照dfs序依次加入的,这点很重要!)。
      • 所以这一条链已经没有多大维护的价值了,我们把这一条链加入到虚树中,具体怎么做呢?
      • 假如栈顶为p,栈中的第二个元素为q。
      • 当dfn[q]>dfn[Lca]这时q还在Lca子树内,q->p连边,弹出栈顶。
      • 当dfn[q]==dfn[Lca]这时q为Lca,q->p连边。
      • 当dfn[q]< dfn[Lca]这时元素q还有维护的价值(可以q->Lca->v构成一个新的链),Lca->p连边,弹出栈顶,Lca加入栈。
      • 最后插入v。

    等点全部加完后,记得把栈中的所有点加到虚树里去。(这是初学者容易犯的错误)
    这样一棵虚树就建好了。


    推荐几道模板题:
    [Sdoi 2011]消耗战
    [Heio 2014]大工程

  • 相关阅读:
    Cogs 465. 挤牛奶
    洛谷P1083 借教室
    Cogs 1264. [NOIP2012] 开车旅行(70分 暴力)
    2017-10-19 NOIP模拟赛
    Codevs 2144 砝码称重 2
    洛谷P1450 [HAOI2008]硬币购物
    洛谷P2534 [AHOI2012]铁盘整理
    洛谷P1731 生日蛋糕
    2017-10-18 NOIP模拟赛
    洛谷P1074 靶形数独
  • 原文地址:https://www.cnblogs.com/gzy-cjoier/p/7622928.html
Copyright © 2020-2023  润新知