字符串问题之有趣的字符串题目1-范斯喆(day18)
A. Palindrome Partition [CF1827C]
如果一个长度为偶数的回文字符串的一个后缀同样也是长度为偶数的回文字符串,则这个字符串一定能被分成三个更小的长度为偶数的回文字符串。那么我们只需要这些最小的长度为偶数的字符串。
定义 \(f_i\) 表示以 \(i\) 结尾的满足题目条件的字符串有 \(f_i\) 个,则答案为 \(\sum{f_i}\)。
考虑如何转移,假设以 \(i\) 结尾的最小的长度为偶数的回文字符串长度为 \(ln_i\),则 \(f_i=f_{i-ln_i}+1\)。
那么只需要求到 \(ln_i\) 即可,做一遍 \(\text{Manacher}\),用单调栈找到最近的能包含到 \(i\) 的 @
字符就行了。
B. Palindromic Problem [CF1913F]
先用 \(\text{Manacher}\) 求出不改字符的个数,然后直接计算每个字符更改后的增减情况。
对于会跨过 \(i\) 的回文串,强制把边界减小到 \(i\),用差分维护。
对于边界与 \(i\) 相邻的回文串,把 \(i\) 改成另一边对应的字符,再 \(\text{Hash} +\) 二分得到能继续扩展多远。
对于既不跨过也不相邻的,就没有影响。
最后算贡献的时候多考虑一下,有一些特判要注意。
C. 简单的字符串问题 [luogu P10716]
先 \(\text{kmp}\) 建出失配树,可以知道每个 \(A\) 一定是 \(S[1,i]\) 的祖先,所以我们只需要找到最深的能满足条件的祖先,答案就是它的深度。
考虑一个 \(f_{i,j}\) 表示对于 \(S[1,i]\),不重叠的出现 \(j\) 次,最早是在 \(f_{i,j}\) 处。
我们遍历一遍失配树,用 \(\text{set}\) 启发式合并地维护 \(i\) 的子树中所有的位置。由于每个 \(i\) 最多跳 \(\lfloor\frac{n}{i}\rfloor\) 次,所以暴力在 \(\text{set}\) 里 \(\text{lower_bound}\) 找就行了。时间复杂度是 \(\text{O(nlog^2n)}\) 的。
最后在树上倍增找到最深的满足 \(f_{p,k} \ge i\) 的,输出深度。
E. Zimpha Fan Club [CF1975G]
可以把边界都先缩减到每边一定有一个是 *
,同时判断缩减是否成立。
缩减完成后,如果两个串都有 *
,则一定是可行的。
否则我们令有 *
的串为 \(S\),没有的为 \(T\)。问题转换为了把 \(S\) 中被 *
分开的那些串按顺序对应到 \(T\) 上且不重叠。
对于这个通配符 -
,我们令它的值为 \(0\)。我们用多项式来解决。令 \(f_i = \sum\limits_{j,k}(a_j-b_k)^2a_jb_k[j+k=i]\)。
把这个式子拆开用 \(\text{FFT}\) 计算。
把 \(S\) 的子串翻转后与 \(T\) 相乘的到 \(f\),对于 \(f_i=0\) 的位就表示可以匹配到那一位。
每次只计算 \(S\) 和 \(T[now,now+|S|\times 2]\),这样不管是否找到可匹配位,都可以至少减少 \(|S|\) 个 \(T\) 中的位置,保证时间复杂度。
简单的字符串问题 2 [luoguP11291]
因为 \(R_i\) 可以是空串,所以当 \((l,r,k)\) 满足条件时,\((l,r,k+1)\) 也一定满足。
同时注意到有单调性:\((l,r,k)\) 不满足时,\((l,r+1,k)\) 也一定不满足。