CF526G Spiders Evil Plan(树上最优性问题、倍增+线段树)

这篇博客讨论了如何解决一个关于树的最优性问题,其中目标是找到最大的边权和,同时覆盖指定点。作者提出了一种策略,包括将询问点作为根进行分析,并利用DFS序的线段树或长链剖分来预处理答案。解决方案涉及贪心选择最大贡献的叶子节点,并考虑直径两端点作为根的情况。博客中还提出了一个时间复杂度为O((n+q)logn)的算法,并提出了一个问题关于是否需要同时考虑直径两端点作为根的情况。
摘要由CSDN通过智能技术生成

Description

一棵 n 个结点的树,有正边权。
用 y 条链覆盖这棵树,满足:

  • 所有链连通(有重点即算作相连)
  • 点 x 被覆盖
  • 被覆盖的边的权值和尽可能大
    q 次给出 x, y,询问最大边权和,强制在线。
    n, q ≤ 1 0 5 10^5 105

Solution

  • 可以发现一些比较显然的性质:
  1. 权值是正的,那么链的端点一定可以全部调整成叶子。
  2. 如果链不连通,可以交换链的端点使它们连通。
  3. 使用 k 条路径就可以覆盖一棵有 2k 个叶子的树。(先以任意方式匹配叶子。如果有两条路径不相交,可以调整成相交的情况。
    不断调整就可以让任意两条路径都相交,于是显然覆盖了整棵树。)
  • 现在问题是寻找 2 ∗ y 个叶子,使 x 被包含,使被包含的边权和最大。
  • 考虑单次询问怎么办。如果只有一次询问,我们就把询问的点 x 提作根,如果 x 的度数不为 1 ,那么选 y 条路径的最优方案必然可以转化为选 2y 个叶子,然后求这 2y 个叶子到 x 的路径的并的长度。如果 x 的度数为 1 的话,那么就是选 2y-1 个叶子,因为有一条路径要从 x 出发。
  • 那么显然就可以贪心的选当前贡献最大的叶子加入答案了。
  • 如果有多组询问呢?每次询问都换根显然不现实,但发现每次询问中,一定存在一种方案使得直径的两端中至少有一端被选取。
  • 那我们就可以把直径的两个端点分别作为根来考虑,最后询问的时候取最大值即可。
  • 考虑对每棵树预处理出 a n s i ans_i ansi 表示当前选了 i 个叶子的最大权值和,这个可以用 DFS序的线段树或者是长链剖分来实现。
  1. 线段树实现:每个叶子节点的贡献是 它的深度-它到根路径上已经被其它路径覆盖的部分的长度,用线段树维护一下叶子的贡献,每次贪心的选取贡献最大的叶子
  2. 长链剖分实现:一个子树内,最先被选的显然是深度最大的叶子,那么一个叶子的贡献,就是在长链剖分后,所在重链以及上方第一条轻边的距离。
  • 然后考虑一次询问 x,y。如果 a n s 2 y − 1 ans_{2y-1} ans2y1中包含了 x 点,那么直接输出 a n s 2 y − 1 ans_{2y-1} ans2y1即可。否则,加入 x 子树内最深叶子,然后需要删去一个之前选的叶子,使得减少的权值最小:
  1. 这个叶子可能是最后一个被选的叶子,也就是贡献最小的那个。
  2. 由于 x 的加入,与 x 的 lca 最深的被选叶子的贡献可能会减小,而被删去。(找离 x 最近的有叶子被选的祖先的一条路径,砍掉一半后跟 x 的子树中深度最大的点接上。)
  • 可以发现,第一种情况好办,倍增跳到到第一个被访问时间 ≤ 2 y − 2 \leq 2y-2 2y2 祖先 u ,那么答案就是 a n s 2 y − 2 − d e p [ u ] + m x [ x ] ans_{2y-2}-dep[u]+mx[x] ans2y2dep[u]+mx[x]
  • 然后考虑第二种情况。第二种情况乍一看需要维护在所有时间所有点的子树内选的叶子节点的权值的最小值,这个很麻烦。但是仔细想想可以发现,只有在这个祖先的子树内只有一个叶子节点被选的时候,这种情况才可能有第一种情况优。因为如果多于两个叶子,那么删掉最小的那个叶子节点所减去的依旧是这个点加进来时候的权值,既然是减去加进来的权值那么第一种情况显然是最小的。如果只有一个叶子&#x
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值