NOIP2020 T2

给定长度为 \(n(1 \le n \le 2^{20})\) 的字符串 \(s\),问有多少种合法的拆分方式?一种合法的拆分方式:

  • \(s = (AB)^iC(i > 0)\)其中 \(A,B,C\) 为非空字符串,\((AB)^i\)\(i\)\(AB\) 拼接的结果。
  • \(F(A) \le F(B)\) \(F(s)\) 表示 \(s\) 中出现奇数次的字符数。

先忽略第二个条件。显然可以把 \(AB\) 看成一个整体(题目给了很强的提示),枚举 \(AB\) 的长度 \(len\),用 hash 判断每个 \(i\) 是否可行。

由调和级数可知,至多由 \(n \log n\)\(i\)。每个 \(i\)\(len - 1\) 种选法。

接下来考虑第二个条件,可以预处理出 \(s\) 有段后缀的 \(F_i\) ,然后将长度为 \(1 \sim len - 1\)\(F\) 丢到数组里(表示 \(A\) 的选法),查询 \(F_{i\cdot len + 1}\) 对应的贡献即可。

因为 \(F \le 26\),直接暴力加贡献即可。(否则还要个树状数组,时间复杂度是 \(O( n\log n\log26)\))。

时间复杂度:\(O(n (\log n + 26))\)

注意下常数能过,似乎有 \(O(n)\) 的扩展 KMP 做法。

posted @ 2025-10-17 21:59  xiehanrui0817  阅读(4)  评论(0)    收藏  举报