加载中...

ABC 452 G

G - 221 Substring

题目本质上是求满足某一限制的本质不同子串数量,可以考虑使用后缀数组、后缀自动机。

将原串改造成若干二元组 \((num_{i}, cnt_{i})\) 构成的序列,其中 \((num_{i}, cnt_{i})\) 表示连续 \(cnt_{i}\) 个数字 \(num_{i}\)

分类讨论:

  • \(num_{i} = cnt_{i}\):可以被随意选取
  • \(num_{i} < cnt_{i}\):只能选取长度恰为 \(cnt_{i}\) 的前缀或后缀
  • \(num_{i} > cnt_{i}\):无论如何都不能选取

做法1:后缀数组

考虑按照上面的 3 种情况,改造原串:

  • \(num_{i} = cnt_{i}\)\((num_{i})\)
  • \(num_{i} < cnt_{i}\)\((num_{i}, 0, num_{i})\)
  • \(num_{i} > cnt_{i}\)\((0)\)

对于改造后的字符串,问题便等价于求不包含 0 的本质不同子串数量。

若没有不包含 0 的限制,便是经典结论:任意一个字符串,本质不同子串个数为 所有子串个数 $ - \sum_{i=1}^{n} height_{i}$。

将这个结论稍微改写一下:设排名为 \(i\) 的后缀的长度为 \(len_{i}\),则答案为:

\[\sum_{i=1}^{n} (len_{i} - height_{i}) \]

我们要求统计的子串中不包含 0,那也就意味着对于任何一个后缀,必须在从左往右第一个 0 的位置处截断计数。设 \(len'_{i}\):排名为 \(i\) 的后缀中,不包含 0 的最长前缀长度。

分两种情况讨论:

  • \(len'_{i} > height_{i}\):净贡献为 \(len'_{i} - height_{i}\)
  • \(len'_{i} \le height_{i}\):净贡献为 \(0\)

因此不包含 0 的本质不同子串数量最终可以用以下式子表示:

\[\sum_{i=1}^{n} \max(0, len'_{i} - height_{i}) \]

\(len'_{i}\) 可以通过倒序遍历字符串 \(O(n)\) 预处理出来。

code

做法2:后缀自动机

等学了 SAM 后再补。

code

posted @ 2026-04-09 13:54  小橘奏  阅读(18)  评论(0)    收藏  举报