P1117 [NOI2016] 优秀的拆分
先考虑求出 \(AA\) 的形式有多少。
两个子串相等,可以看作是对于某两个点,它的 LCP 和 LCS 正好覆盖了这两个串。而两个串之间的距离正好是这两个点的距离减去字符串的长度。
那么我们可以枚举一个长度 \(len\),然后每隔 \(len\) 放一个关键点,这样任意一个长度为 \(len\) 的子串一定覆盖了一个关键点。然后对于每一个关键点,计算出 \(i\) 与 \(i + len\) 的 LCP 和 LCS,如果 LCP + LCS \(\ge\) len,那么就相当于可以选出两个距离为 \(0\) 的相等的子串,也就是 \(AA\) 串。
可以选择的串有 LCP + LCS - len + 1 种。
调和级数求和是 \(O(n \log n)\) 的,所以关键点总数是这个数量级。
\(AABB\) 就直接统计出来每一个前缀的 \(AA\) 和每一个后缀的 \(AA\) 乘起来即可。
UVA10829 L-Gap Substrings
一模一样,只不过相当于变成了两个串间隔为 \(g\),那就计算 \(i\) 与 \(i + len + g\) 即可。
这玩意恶评吧,怎么这个比上一个弱但是这个是黑啊(