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)\) 预处理出来。
做法2:后缀自动机
等学了 SAM 后再补。

浙公网安备 33010602011771号