1 条题解

  • 0
    @ 2025-10-18 9:09:39

    问题分析

    本题是一道关于字符串处理的综合性问题,核心任务是解决多个查询,每个查询需要统计满足特定条件的字符串子串数量。通过分析代码可知,问题涉及后缀数组(SA)、回文串判定(Manacher算法)和树状数组(BIT)等多种字符串与数据结构技术。

    算法思路

    1. 核心问题拆解

    每个查询要求计算满足条件的子串数量,具体可分解为两部分:

    • 统计满足 Suf[i] < Pre[i+2l] 的子串数量(Suf[i] 表示从位置 i 到结尾的后缀,Pre[i] 表示从开头到位置 i 的前缀反转)
    • 减去同时满足回文条件 s[i,i+2l) 是回文且 Suf[i+2l] < Pre[i] 的子串数量

    2. 后缀数组(SA)的应用

    使用SAIS算法构建后缀数组,用于高效比较字符串的后缀和前缀:

    • 构造拼接字符串 str = s + 'a'-1 + reversed(s) + 'a'-2,其中 reversed(s) 是原字符串的反转
    • 通过SAIS算法计算该拼接字符串的后缀数组 sa 和排名数组 rank,其中 rank[i] 表示位置 i 处后缀的排名
    • 利用排名数组可在 O(1)O(1) 时间内比较任意两个后缀的大小关系

    3. 第一部分计算(First::solve)

    统计满足 Suf[i] < Pre[i+2l] 的子串数量:

    • 将问题转化为比较 rank[i]rank[2n+1-t] 的大小关系
    • 对每个查询构造两个事件(开始和结束),记录需要比较的排名和位置
    • 使用两个树状数组(bit[0]bit[1])分别处理偶数和奇数位置的更新与查询
    • 按位置顺序处理事件,通过树状数组的区间查询功能统计满足条件的数量,时间复杂度为 O((n+q)logn)O((n+q)\log n)

    4. 回文串判定(Manacher算法)

    使用Manacher算法高效计算所有回文子串:

    • 构造扩展字符串(插入特殊字符),统一处理奇数和偶数长度的回文串
    • 计算 maxLen[i] 数组,表示以位置 i 为中心的最长回文串半径
    • 转化得到 R[j] 数组,记录以原字符串位置 j 为中心的最长回文串半径

    5. 第二部分计算(Second::solve)

    统计需要减去的特殊回文子串数量:

    • 筛选满足条件的回文子串,记录其有效范围 [l, r]
    • 对每个查询构造两个事件(开始和结束),表示需要统计的区间
    • 使用树状数组记录回文子串的范围,按位置顺序处理更新和查询
    • 通过树状数组的前缀和查询统计有效回文子串数量,时间复杂度为 O((n+q)logn)O((n+q)\log n)

    关键技术细节

    1. SAIS算法:线性时间复杂度的后缀数组构造算法,核心是通过分类L型(L)和S型(S)字符,递归处理LMS(Left-Most S-type)子串,实现高效排序。

    2. Manacher算法:线性时间复杂度的回文串查找算法,通过利用已知回文串的对称性减少重复比较,核心公式为:

      $$\text{maxLen}[i] = \min(\text{maxLen}[l + r - 1 - i], r - i - 1) \quad (\text{当} \, i < r \, \text{时}) $$

      其中 lr 表示当前已知的最右回文串的左右边界。

    3. 树状数组(BIT):用于高效的区间更新和前缀和查询,支持两种核心操作:

      • 单点更新:O(logn)O(\log n) 时间内更新某个位置的值
      • 前缀和查询:O(logn)O(\log n) 时间内计算某个位置的前缀和

    整体复杂度分析

    • 后缀数组构造:O(n)O(n)(SAIS算法)
    • Manacher算法:O(n)O(n)
    • 第一部分查询处理:O((n+q)logn)O((n+q)\log n)
    • 第二部分查询处理:O((n+q)logn)O((n+q)\log n)
    • 总时间复杂度:O(n+qlogn)O(n + q\log n),可处理 n105n \leq 10^5q105q \leq 10^5 的输入规模

    最终答案计算

    每个查询的结果为第一部分统计值减去第二部分统计值,即:

    $$\text{ans}[i] = \text{count}_1[i] - \text{count}_2[i] $$

    其中 count1[i]\text{count}_1[i] 是满足 Suf[i] < Pre[i+2l] 的数量,count2[i]\text{count}_2[i] 是需要减去的特殊回文子串数量。

    • 1

    信息

    ID
    3276
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者