P3233 [HNOI2014]世界树(虚树/倍增/动态规划)

本文介绍了如何利用数据结构解决HNOI2014中关于控制点查询的问题。首先建立虚树,处理特殊情况,然后使用栈维护右链并建立边。接着进行动态规划计算每个点的最近控制点。对于不同类型的点,分别讨论它们的控制情况,如直接连接到虚树节点的点和虚树节点间的节点。最后,通过倍增算法找到分割点,计算答案。整个过程涉及到树的遍历、动态规划和区间查询等技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

P3233 [HNOI2014]世界树

每次给出mi个点,查询每个点控制的点的个数,每个点由离他最近编号最小的点控制。

首先按照套路建出虚树,注意特判1节点,然后用栈维护右链,然后不断弹栈建边。
然后进行dp,求解出虚树上每个点的最近控制点,对于控制点就是自己,需要两边dfs,第一遍处理子树,第二遍从上到下dp,这样就处理出在整个树上的控制点。

然后对于其他点我们需要分类讨论:

第一类就是直接连接到虚树节点上,但是不包含虚树节点的子树,这些点必然由g[u]控制,具体计算size可以用siz[u]减去包含虚树节点的siz。

第二类就是在虚树节点之间的节点,这一部分是一个链上挂了许多子树,并且其中没有虚树节点,这一部分要么由g[u]控制,要么由g[v]控制。然后中间必然有一个分割点,我们可以考虑倍增求解这个点的位置。
然后计算答案还需要知道v所对应子树是u的哪一个儿子,这个也可以通过倍增求解,然后就可以用这些点来计算对应这一部分的贡献了。
注意这里的虚树节点可能是lca节点,所以对应贡献必须计算到g[u]和g[v]上。

代码细节:

  1. 建立虚树的时候一定要小心,每次弹栈都需要建边
  2. 还有倍增寻找分割点的时候要注意,两端点属于同一个控制点的情况,虽然可以直接处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值