1 条题解
-
0
题意简述
长度为 的街道,每个位置 有法力水晶种类 。
每个法师在位置 ,喜欢的水晶种类区间 。
需要收集所有在街道上存在且法师喜欢的种类,每个种类只需一个。
法力消耗 = 所选水晶位置到 的距离之和。
求最小总消耗。
关键观察
对每个种类 ,如果街道上有多个位置有该种类,我们应选择离 最近的那个,这样消耗最小。
因此问题转化为: 对 且 在街道上出现,求 ,然后求和。
问题难点
直接枚举种类会超时( 最大 ,种类区间可能很大)。
需要快速找出在 内且实际在街道上出现过的种类,并求最小距离。
思路
预处理
对每个种类 ,记录它在街道上出现的所有位置(按坐标排序)。
查询处理
对于查询 :
我们只关心在 内且街道上出现过的种类。
对每个这样的种类 ,在它的位置列表中二分查找离 最近的位置,计算距离 。
答案 = 。
但这样仍然可能超时,因为种类区间内实际出现的种类数可能很多。
优化
注意到位置是 1 到 n,我们可以换个角度:
对每个位置 ,它提供种类 ,且它到 的距离是 。
我们想要:对每个在 内的种类,取它所有位置中距离 最小的。
这相当于: 对每个种类 ,取 求和。
更高效的方法
我们可以离线处理:
把查询按 排序(或者分治?)。
用数据结构维护当前“最近位置”信息。
但这里有一个经典做法: 只考虑每个种类在 左边最近的和右边最近的位置,因为最小距离一定来自左边最近或右边最近的出现位置。
最终算法框架
对每个种类 ,记录所有出现位置(有序列表)。
对查询 :
初始化答案 = 0
对 从 到 :
如果 在街道上出现过:
在 的位置列表中二分找到 的第一个位置,得到右边最近位置
左边最近位置 就是 的前一个(如果存在)
计算 并累加
输出答案
但这样最坏 会超时。
正解思路(莫队 + 平衡树/分块)
实际上,这个问题是 区间种类最小距离查询,比较复杂。 一种可行方法:
把“种类”看作“颜色”,问题变成:区间 内所有颜色,求它们到 的最小距离之和。
可以按 排序查询,用双向链表维护每个颜色的最近出现位置,用树状数组/线段树维护距离和。
但实现较复杂。
简单可行方案(针对部分分)
对于 可以直接暴力:
对每个查询,枚举所有位置 ,如果 ,则更新种类 的最小距离。
然后累加。
对于 (种类=位置)的情况:
那么 内存在的种类就是 本身。
每个种类 的最小距离就是 。
答案 = ,可以 公式计算。
对于 :
所有种类都存在,答案 = ,可以预处理。
总结
本题是较难的区间种类查询问题,需要复杂数据结构(莫队/分块/线段树+预处理最近位置)才能 AC 全部数据。 核心是快速求区间内各颜色到某点的最小距离和。
- 1
信息
- ID
- 5367
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者