1 条题解
-
0
自动搬运
来自洛谷,原作者为

FutaRimeWoawaSete
Dear the f**king destiny!搬运于
2025-08-24 22:36:54,当前版本为作者最后更新于2022-03-17 17:00:39,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
每次讲都是脑子会了嘴巴没会,但万幸的是手还会写题解/hanx
场上题都不知道是什么但万幸没开,毕竟我树分块早就忘完了更别说想到了(
不过想到树分块貌似就简单了?
有向邻域的不删除莫队。
先以一般的角度考虑这个问题:这是一道构造题!人畜无害,一点也不数据结构!
观察 ,大概是 的数量级,分块吧。
这里默认大家都会 top cluster 树分块,不会的可以参考 我的博客(不过现在个人觉得讲的不是很好),gxy001 的博客,以及
青蛙的集训队论文《浅谈一类树分块的构建算法及其应用》,这里不重点展开。不过您也可以选择先看完这篇题解之后再去学习 top cluster 树分块,我会把需要的东西都大致讲一下,划分方法可以看完再去学。
简要地讲解一下:top cluster 定义簇为树上的连通块。树分块将一棵树分成了许多个簇,这些簇只有二度簇(可以理解成簇内只有两个端点与其他簇联通),一度簇(簇内只有一个端点与其他簇联通)。
而很显然,簇之间的交只有可能是各自的端点。
并且若设置一个阈值 ,该种分法将所有簇的大小控制在 以内,将簇的个数控制在 之内。
这里给出对样例的树的划分来辅助理解:
其中不同的颜色代表不同的簇。
考虑在进行划分之后,我们对所有的询问 进行分类:
-
若 处于一个二度簇的两个端点的路径上,将这个询问归类为 类询问,挂到二度簇里深度较深的端点上;
-
其余的询问都是 类询问。
考虑对于 类询问,我们对于每个二度簇进行处理。可以先处理出每个节点在根为 时的深度,记第 个簇深度较深的端点为 ,将挂在 的所有询问 拿出来,按照 的大小进行排序。
这里再来一张图,就不信看不懂了。
假设排序后询问 排在 前面:
其中棕色的部分表示两个询问的有向邻域包含的点中,在簇内的部分;未涂色的部分表示不在簇内的部分。
考虑这么构造操作:若当前处理排序后第 个询问,记 ,则跳到 ;然后跳到 声明后撤回此次跳跃,再跳到下一个 去处理第 个询问;处理完当前簇的所有询问时回到 。
我们发现,这样的跳跃在按照 排序后总是合法的;考虑每次跳跃的代价就是相邻两个有向邻域点量的差异,对于从 跳到 ,增加的只会是树簇内的点,即对于每个询问摊一个 的代价,若 类操作一共有 个,则此处的贡献代价是 。
对于从 跳到下一个 ,每次只会向 的子树内扩展,对于每个簇的贡献代价不超过 ,则此处的贡献代价是 。
综上,我们证明了对于 类询问的总贡献代价不超过 ,操作次数为 。
对于第二类询问,其 有可能处于一个一度簇内,有可能处于二度簇的非路径节点上,不过不管 怎么变,其有向邻域所能囊括的点都在 所在的簇内,其大小不超过 ,所以直接跳过去声明后跳回 就行了,设一共有 种二类操作,这里的贡献代价不超过 。
综上我们得到了一种贡献代价不超过 ,操作次数为 的方法。细心的读者可能发现对于贡献代价中 也不是一个完全严格的上界,,因为当 一大了块也分不到这么多块,实际操作下来根本卡不到这么多,至于开 不知道是不是就是这种做法的实际严格上界,不过我太菜了还不会完全证明。
最后提一下关于此题的树分块方法。由于我们只用知道每个簇的端点,所以只用记录每个节点下方是否有簇端点,子树内未被划入簇的点数量,当前节点所属簇的 即可正确划分。
-
- 1
信息
- ID
- 7560
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者


