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

Petit_Souris
鼓励的话语 无论多少次我都会说给你听 | 你在名为弱小的深渊 究竟看见过什么 | 天空中出现了一种罕见的天文现象搬运于
2025-08-24 22:56:45,当前版本为作者最后更新于2024-06-05 23:40:57,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
这种码量的数据结构题感觉放到正式考场上做出的概率 < 10%......在相对冷静的情况下也从 20:40 开始看题,不看题解做到 23:20 才完成调试和卡常,成功通过。(而且还是 IOI 赛制的情况下,虽然没测大样例)
首先考虑给定一个序列 怎么快速求解。由经典结论,设 为 中比 大的数量,那么每经过一轮冒泡排序, 序列的每一项 都变化为 ,接着整个 序列整体左移一位,删除 ,末尾补 。
那么现在我们得到了 轮冒泡排序后的序列,相当于已知 轮后的 序列,那么倒退回 轮前,对于 ,如果 ,那么 必然为 ,否则, 可以取 中任意值。综上,容易总结得到答案为 ,其中 为前缀最大值的数量。(当然还需要特判无解的情况,即 的最后 个元素非单调或最后 个不是最大的 个的情况)
现在问题转化为给定树上一条链,求出前缀最大值数量。有很容易的 :考虑树剖 + 楼房重建线段树,在 dfs 序列上建立线段树,维护每个节点最大值和前缀最大值的数量。(不展开细节,见 P4198)(考场上想不清楚的时候,性价比最高的做法,因为在链上是 可以直接顺带通过,而且树剖和楼房重建线段树常数都不大,应该可以通过除了最后一个包以外的所有点,个人预计半小时就能写完调完)
但是现在是赛后,我们不能止步于此。考虑更细致地分析性质。设路径为 ,那么 这一段是容易分析的,每次向上跳到最近的比当前点权值大的最深的点即可,这个点是可以预处理出来的,预处理后建立倍增数组即可。假设现在在 之前跳到的最后一个点是 。
我们现在要求 的前缀最大值数量。 这段上已经没有新的最大值了,所以我们要找到 路径上第一个 的点。这个点可以通过树链剖分,拆分成 条链,依次枚举每条链,如果这条链上已经有 的点了(区间最大值,st 表 查询),就在这条链内部二分。每次查询只会二分一次,复杂度是 的。设这个点为 。
最后剩下 这一段。我们已经预处理了每个点往上第一个比他大的点,设其为 ,那么一个这段路径上的点 被计算贡献当且仅当 (如果 显然就被半路掐掉了),这是一个链上一维数点,可以离线之后 dfs 一遍树,用树状数组维护。
别忘了前面一个预处理没有解决。回顾一下,我们需要求出每个点上面第一个比他大的点,一个 naive 的想法是 dfs 的同时维护单调栈,每次直接二分一个点,但是直接维护显然 push,pop 次数可能达到 ,需要可持久化的结构,但是这就很麻烦了。还不如直接建立一棵线段树,每次二分一个后缀即可。时间复杂度 。
还剩下一个判断是否有解。最后 个数是递增的是好判断的,直接前缀和就行了。判断是否是最大的 个只需要求出前缀的 和后缀的 进行比较即可。复杂度也是 的。
综上,总时间复杂度为 。常数比较大,建议不要到最后来卡常,写的过程中就注意实现。
代码实际上预处理部分写了 ,因为这个常数小,对效率影响不大。(共 6kb,但是想清楚了每个 part 分开看还是相当容易的)
- 1
信息
- ID
- 10027
- 时间
- 4000ms
- 内存
- 512MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者