1 条题解
-
0
算法标签
前缀和、ST表(稀疏表)、优先队列(堆)、贪心
问题分析
我们需要从所有长度在 之间的连续音符子数组(超级和弦)中,选出 个不同的子数组,使得它们的美妙度之和最大。
关键观察
- 连续子数组的美妙度可以用前缀和快速计算:子数组 的美妙度为 (其中 是前缀和数组)。
- 对于每个左端点 ,合法的右端点范围是 ,我们需要在这个范围内找到使 最大的 ,并通过贪心和堆结构来选择前 大的子数组。
核心算法思路
1. 前缀和与ST表预处理
- 计算前缀和数组 ,用于快速得到任意子数组的和。
- 构建ST表(稀疏表),用于在 时间内查询区间 内使 最大的位置 ,从而快速得到以 为左端点的最优右端点。
2. 优先队列(堆)的贪心选择
- 对于每个左端点 ,确定其合法右端点范围 (,),并找到该范围内使 最大的 ,将该子数组的信息(左端点、右端点范围、最优位置、美妙度)存入大根堆。
- 每次从堆中取出当前最大的子数组,累加到答案中。然后将该子数组的“左半部分”()和“右半部分”()的最优子数组信息重新插入堆中,确保后续能选择到次大的子数组。
3. 时间复杂度分析
- ST表预处理:。
- 初始入堆操作:(每个左端点入堆一次)。
- 堆操作:每次堆操作是 ,共进行 次,总时间 。
- 整体时间复杂度为 ,可满足题目中 、 的数据范围。
总结
本题通过前缀和快速计算子数组和,ST表快速查询区间最大值位置,结合优先队列(堆)的贪心策略,高效地选出了 个最大的不同超级和弦,从而得到乐曲的最大美妙度。这种方法充分利用了数据结构的特性,在时间和空间复杂度上都能满足题目要求。
- 1
信息
- ID
- 5142
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者