PrepStack · Markdown HTML

前缀状态 + 哈希频次

前缀、差分与哈希状态 · HTML

数学 / 逻辑形态

若区间 (j,i] 合法等价于 relation(P[i],P[j]),扫描当前 P[i] 时查询所需历史 key,再把 P[i] 加入表。

识别信号

容易误判的相似信号

SignalWhy it is different
只需一次区间和查询普通 prefix-sum 更简单,无需哈希历史。
状态无法紧凑编码若前缀摘要维度随 n 增长,哈希状态可能不可行,需要别的结构。

核心不变量

处理位置 i 前,哈希表精确保存所有允许作为左边界的历史前缀状态;查询先于插入可避免错误使用未来或自身状态。

状态、转移与处理顺序

ItemDefinition
State当前前缀 P、历史状态→频次(计数)或最早索引(最长),以及答案。
Transition更新当前 P;计算匹配历史 key 并贡献答案;再记录当前 P。
Frontier / order扫描位置左侧的全部历史前缀,被哈希表按状态压缩,而非保留所有区间。

Python 骨架

def count_target_sum(values, target):
    prefix = 0
    frequency = {0: 1}
    answer = 0
    for value in values:
        prefix += value
        answer += frequency.get(prefix - target, 0)
        frequency[prefix] = frequency.get(prefix, 0) + 1
    return answer

正确性思路

  1. 区间 j..i 的和为 P[i+1]-P[j],等于 target 当且仅当历史前缀为 P[i+1]-target。
  2. frequency 保存每种合法历史前缀的出现次数,查询值正好是以当前右端结尾的合法区间数。
  3. 每个区间由其右端那一轮唯一计数,故既不漏也不重。

复杂度

TimeSpaceParameters
期望 O(n)O(n)n 为元素数;哈希操作按期望 O(1),不同前缀状态最坏 n+1。

边界条件

错误模式

PatternWhy it fails / fix
忘记空前缀从索引 0 开始的合法区间会全部漏掉。
先插入再查询某些目标下会把零长度区间错误计入;明确边界语义。
计数与最长混用存储计数存 frequency,最长存 earliest index,目标不同。

选择与排除规则

相关模板

RelationTemplateBoundary
单调情形替代可变长滑动窗口非负值使 left 可单调移动。

原创微型例子

环节内容
Result合法区间共有 3 个。
Setup值 [2,-2,2],目标和 2。
Trace前缀依次 2,0,2;两次遇到 2 都能匹配历史 0,最后一次还有不同左边界。

Recall prompts

我的补充