P7897 [Ynoi2006] spxmcq

并不太难的一个 Ynoi。

首先考虑一个暴力 dp。$f_u$ 表示 $u$ 结点的答案。则有:

$$f_u=a_u+x+\sum_{u\to v}\max(f_v, 0)$$

后面的东西不太好处理,我们注意到 $0$ 是无效转移,于是我们维护一个新的结构,在 $f_v\ge 0$ 时才将 $u\to v$ 这条边连上。容易发现这是一个森林。在这个森林中,一个点的答案即为

$$f_u=a_u+x+\sum_{u\to v}f_v$$

展开发现 $f_u$ 本质为 $siz_u\cdot x+tot_u$,其中 $siz_u,tot_u$ 表示森林中的 $u$ 的子树中结点个数与权值之和。看起来十分好维护了。

而随着 $x$ 的增加,$f_u$ 显然不减,于是我们得到的森林的边集是有包含关系的。这启发我们去离线询问,按 $x$ 升序排序,然后去动态地维护森林。每条边只会更改一次状态(从“不出现在森林中”变成“出现在森林中”),所以复杂度是正确的。

什么边会被加入到森林里呢?此时有 $siz_u\cdot x+tot_u\ge 0$,于是 $x\ge \left\lceil-\dfrac{tot_u}{siz_u}\right\rceil$,也就是说森林中一个根节点在原树中通往父亲的那条边可以被连上,当且仅当当前询问的 $x$ 不小于 $\left\lceil-\dfrac{tot_u}{siz_u}\right\rceil$。如何快速找出这样的边呢,使用 multiset/set 维护即可。

那么,现在问题转化为了:

  • 在森林中连边
  • 维护森林中每个点的 $siz_u$ 和 $tot_u$

考虑连上一条边对所要维护信息的影响。记这条边深度较大者为 $u$,其父亲也就是这条边的另一个端点为 $fa_u$,其父亲所在联通块的根为 $p$。而更新了 $siz$ 和 $tot$ 的结点,恰好是 $fa_u$ 到 $p$ 的路径上的点,并且是简单的链加操作。使用树状数组维护 dfn 序树上差分即可。找联通块根使用并查集实现。

此题卡常,AC 记录最大点 2.98s,不保证任何时候均可使用此代码通过本题。

Code

posted @   TernaKagiri  阅读(24)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示