BZOJ #3653. 谈笑风生

本文介绍了一种基于树形结构的动态规划算法,并提供了两种实现方式:一种是以节点为中心的DP,另一种则是通过优化合并操作来简化计算过程。该算法用于解决特定路径选择问题,旨在寻找最优解。

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

题目

题意:
给定一棵树.
询问给定 b , k b,k b,k,现在要选择离 b b b距离 ≤ k \le k k单位的点 a a a和无限制的 c c c,使得 a , b a,b a,b都是 c c c的祖先.
问总选择方案数.
n , q ≤ 3 e 5 n,q\le 3e5 n,q3e5

有两种实现方法:
一开始脑抽写了一个以 b , c b,c b,c为中心的 d p dp dp.
具体我们考虑固定一个 c c c的代价:
min ⁡ ( d e p [ b ] − 1 , k ) + min ⁡ ( d e p [ c ] − d e p [ b ] − 1 , k ) \min(dep[b]-1,k)+\min(dep[c]-dep[b]-1,k) min(dep[b]1,k)+min(dep[c]dep[b]1,k).(即考虑 a a a是否为 b b b的祖先)

然后我们发现前面可以快速计算,后面实际上维护一个后缀和就好了.
c o d e code code

然后,看到一个更加简单的做法:
考虑后面一部分,如果我们以 a a a为中心,那么代价为 s z [ a ] − 1 sz[a]-1 sz[a]1.
所以我们直接按深度维护 s z [ a ] − 1 sz[a]-1 sz[a]1的和即可.

啊,你问我为啥维护后缀和?
因为维护后缀和在合并的时候只需要 l e n [ y ] len[y] len[y]的循环次数,
而前缀和要 l e n [ x ] len[x] len[x]次.( l e n [ x ] len[x] len[x]为从 x x x出发的最长链, y ∈ s o n x y\in son_x ysonx)
这样总复杂度就线性啦~~

c o d e code code

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Infinite_Jerry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值