zoukankan      html  css  js  c++  java
  • 莫队算法学习笔记(三)——树上莫队

    前言

    树上莫队的核心思想,就是将一棵树转化成一个序列,然后用普通莫队来搞。

    初始化

    以一棵树为例:

    要想对这棵树进行树上莫队,我们第一步就是用一个(s)数组把它的括号序存下来:

    (id) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    (s) 1 2 4 7 8 8 7 4 5 5 2 3 6 6 3 1​

    同时,我们用(I)数组存储每个数字在括号序列中第一次出现的位置,用(O)数组存储每个数字在括号序列中第二次出现的位置。

    处理查询

    首先,对于询问的两个数(x,y),我们要保证(I_xle I_y)(这可以通过(swap)进行保证)。

    对于查询的两个节点,我们需要对其进行分类讨论。

    对于祖先关系的两个点(以(1,5)为例)

    我们需要分别找到(x,y)在括号序列中第一次出现的位置(即(1)(9))。

    然后就能得到一段区间:

    [1,2,4,7,8,8,7,4,5 ]

    对于出现两次的元素,我们将它去掉(在程序中只要判断一个元素出现次数的奇偶性即可)。

    然后就得到这样一个区间:

    [1,2,5 ]

    而这些恰好就是我们要求解的元素。

    简单说,就是求解区间([I_x,I_y])即可。

    对于非祖先关系的两个点(以(5,6)为例)

    我们需要找出(x)在括号序列中第二次出现的位置和(y)在括号序列中第一次出现的位置(即(10)(13))。

    然后就能得到这样一个区间:

    [5,2,3,6 ]

    注意,对于出现两次的元素,我们同样需要将它去掉,只不过这个例子中刚好没有出现这样的情况而已。

    然后我们可以发现,这个区间中的元素就是除(LCA_{x,y})以外要求解的全部元素。

    则我们单独计算(LCA_{x,y})的贡献,保存答案后再将其贡献减去即可。

    例题

    好好想一下,就可以发现树上莫队其实挺好理解的。

    下面是一道例题:【BZOJ3757】苹果树

  • 相关阅读:
    mysql 存中文乱码
    解决办法:Message: 对实体 "useUnicode" 的引用必须以 ';' 分隔符结尾
    windows无法安装到这个磁盘选中的磁盘具有MBR分区表解决办法
    Windows快速添加开机启动项
    使用markdown做本地笔记软件/编辑器
    Apache负载均衡配置
    setuptools包的使用
    Git clone报错Someone Could Be Eavesdropping On You Right Now (Man-In-The-Middle Attack)!
    Code Review 的项目
    Pytorch 之Torch
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CaptainMotao_on_Tree.html
Copyright © 2011-2022 走看看