虚树学习小记

8 篇文章 0 订阅
3 篇文章 0 订阅

前言

有一类问题,形如:给出一棵n个点的树,每次给出k个关键点,求这些关键点之间的一些信息。
保证∑k和n同阶
而对于一次询问是很好用树形Dp之类的方法解决的。
观察到只有关键点有用,我们可以只保留关键点和两两之间的lca,这就是虚树。
显然虚树的大小是O(k)的,只有dfs序相邻的两个点的lca有用
建出虚树后这类问题我们只需要在虚树上Dp就可以了。
但虚树要怎么建立?

单调栈

我们先把所有点按dfs序排序,按深度维护一个单调栈,表示从栈顶所代表点到根的一条链
接下来我们插入点x,设栈顶为p,我们求出lca=lca(p,x),接下来有两种情况
lca=p,那么我们直接将x入栈
lca!=p,那么我们接着考虑,设栈顶的上一个点为q,又分两种情况
dfn[lca]<=dfn[q],说明p的子树都已经构建完了,我们直接将q->p连边,然后弹栈
dfn[lca]>dfn[q],说明lca夹在q和p中间,那么我们连lca->p,然后弹栈
接着我们判断栈顶是不是lca,不是就把lca入栈,然后再把x入栈
这样子画一画图就可以理解了。
最后我们再把这一条链给连起来就好了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值