【题解】P6779 [Ynoi2009] rla1rmdq

奇怪的好题分享。

题意

P6779 [Ynoi2009] rla1rmdq

给定一棵包含 n 个结点的树,m 个操作以及一个长度为 n 的序列 a,树边带权。

令结点 x 的深度 dep(x) 为根到 x 的路径上所有边的权值和,fa(x) 表示结点 x 的父亲。对于树根 rt,有 fa(rt)=rt

对于每次操作,可以:

  1. 1 l r,表示 lir,令 aifa(ai)

  2. 2 l r,询问 mini=lrdep(ai)

1n,m2×105,1ain,边权取值范围为 [0,109]

思路

小清新分块。

这种玄学树据撅构第一反应就是奇妙根号算法,但是根号分治一类的东西感觉上没有什么前途,对颜色进行分治理论上也不太可行,于是考虑树上莫队或者分块。

注意到空间限制 64MB,然而时间限制 3s。树上莫队做这东西也不好维护,于是可以合理猜测先用玄学分块草,然后再逐块处理卡空间。根号空间复杂度可过。理论存在,实践开始。

第一眼看上去没有什么好的做法,手推一下发现不太能转化成经典问题,于是我们考虑加上一些特殊条件,看一看是否有启发。

假设全局修改,全局查询。

我们发现:假设有两个结点 a,b,使得 b 在经过若干次跳跃之后到达了 a 原本所在的位置,那么 a 对答案的贡献必然包含 b 对答案的贡献,于是可以只继续令 a 向上跳。

换言之,如果某一个结点 u 向上跳跃,到达已经遍历过的结点,那么这个结点对于答案是无意义的。因此只需要每次将对答案可能有贡献的点暴力向上跳,摊下来复杂度是 O(n+q)

如果对于根号个整块,都进行一次上面的操作,那么总复杂度是 O((n+q)n) 的。所以对整块的修改可以直接按上面的方式暴力。

考虑对散块的修改。我们发现对于散块的修改,可能使得它重新成为所处整块中有意义的点。所以我们不妨这样考虑:对于整块修改直接先暴力跳关键点,同时记录下向上跳的步数 k。但是当修改散块的时候,我们考虑将无意义的点向上跳 k 步对齐,然后观察它是否重新获得意义。对齐一次的复杂度是 O(nlogn) 的,无伤大雅。

找祖先可以考虑跳重链,单次复杂度是 O(logn)

于是总复杂度 O(nnlogn)

代码

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