1 条题解
-
0
题目分析
本题要求处理多个查询,每个查询涉及字符串匹配和区间求和。关键点在于:
- 给定字符串
s
和m
个区间[l_i, r_i]
- 每个查询提供一个长度为
k
的字符串w
和区间[a, b]
- 需要计算
sum_{i=a}^b f(s, w, l_i, r_i)
,其中f(s, w, l, r)
表示w[l, r]
在s
中出现的次数
解题思路
核心观察
- 题目中关键限制条件:
∑|w| ≤ 10^5
,意味着所有查询的字符串w
总长度不超过 10^5 - 由于
|w| = k
,所以q * k ≤ 10^5
,这大大限制了查询的复杂度
解决方案
-
预处理字符串
s
:- 构建一个哈希表,存储
s
中所有长度不超过k
的子串的出现次数 - 通过遍历
s
的所有可能子串(长度从 1 到k
)来填充该哈希表 - 使用双哈希避免哈希冲突,确保准确性
- 构建一个哈希表,存储
-
处理每个查询:
- 对于查询的字符串
w
,计算其所有子串(长度从 1 到k
)在s
中的出现次数 - 构建一个映射
map_w
,将每个子串映射到其在s
中的出现次数 - 对于每个区间
[l_i, r_i]
(i
从 0 到m-1
):- 提取
w[l_i, r_i]
作为子串 - 从
map_w
中获取该子串在s
中的出现次数 - 将次数存储在数组
count_w
中
- 提取
- 对于查询的字符串
-
区间求和:
- 为
count_w
数组构建前缀和数组 - 对于查询的
[a, b]
,通过前缀和快速计算sum_{i=a}^b count_w[i]
- 为
优化与复杂度分析
- 预处理复杂度:O(n·k),其中
n
是字符串s
的长度,k
是查询字符串的长度- 由于
k
较小(因为q·k ≤ 10^5
),该复杂度可接受
- 由于
- 查询处理复杂度:O(q·k² + m)
- 计算
w
的所有子串:O(k²) - 为每个区间查询:O(m)
- 由于
q·k ≤ 10^5
,总复杂度在可接受范围内
- 计算
边界情况处理
- 空字符串处理:当
l_i > r_i
时,子串为空,出现次数为 0 - 无匹配子串:如果
w[l_i, r_i]
在s
中不存在,出现次数为 0 - 长度不匹配:当
r_i - l_i + 1 > k
时,应视为无效查询(但题目保证0 ≤ l_i, r_i < k
,所以这种情况不会发生)
实现要点
- 使用双哈希技术提高哈希表的准确性
- 利用前缀和数组实现区间求和的 O(1) 查询
- 由于字符串由小写字母构成,可以使用简单的基数哈希函数(如 'a'→0, 'b'→1, ..., 'z'→25)
总结:
本题通过预处理字符串
s
的子串频率,结合查询时的子串频率计算和前缀和优化,实现了高效处理多个查询的目标。 - 给定字符串
- 1
信息
- ID
- 3200
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者