莫队算法学习笔记(三)——树上莫队

前言

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

初始化

以一棵树为例:

1522397-20181128201959941-723961591.png

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

\(id\)12345678910111213141516
\(s\)1247887455236631​

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

处理查询

首先,对于询问的两个数\(x,y\),我们要保证\(I_x\le 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】苹果树

转载于:https://www.cnblogs.com/chenxiaoran666/p/CaptainMotao_on_Tree.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值