ISIJ 2018 奇怪的字符串(Training Round D6T1)
无忧公主 2018-07-10
题目描述
考虑字符串 s 仅由小写字母组成,例如 “abba”。定义 W(s) 为 s 所有本质不同的连续子串的集合,例如 W(“abba”) = { “a”,”b”,”ab”,”ba”,”bb”,”abb”,”bba”,”abba” }。定义 Y(s) 为 s 所有本质不同的非连续子串的集合,例如 Y(“abba”) = W(“abba”) ∪ { “aa”,”aba” },显然 W(s) 是 Y(s) 的子集。
对于一些奇怪的字符串 s 满足 W(s) = Y(s),例如 “abba” 就不是奇怪的,但 “abb” 是奇怪的因为 W(s) = Y(s) = { “a”,”b”,”ab”,”bb”,”abb” }。现在小明有一个字符串 s,请你求出 W(s) 中有多少个字符串是奇怪的?
注意:集合中的所有元素互不相同
限制
1s 256M
1≤|s|≤ 200,000
输入格式
一个字符串 s
输出格式
一个整数,表示 W(s) 中有多少个字符串是奇怪的
输入样例
abba
输出样例
7
样例解释
abba 的所有连续子串中,除了 abba 以外都是 ” 奇怪的 “
题解
通过观察可以发现,s 是 ” 奇怪的 ” 的条件是形如 aaaa 或 aaabbbb。对于连续的一段字母进行 “ 压缩 ” 扫描线处理,记录同种字母 k 的最大连续长度、字母 k1 在固定长度 c1 后面接字母 k2 的最大长度,以将本质不同(这是最麻烦的地方)的字符串区分开来。这些均可用数组和 map 维护(容易 MLE),并最后一边维护最大值一边统计答案。
#include <bits/stdc++.h>
using namespace std;
template <typename T> void read(T &t) {
char ch=getchar(); int f=1; t=0;
while ('0'>ch||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
do { (t*=10)+=ch-'0'; ch=getchar(); }