1 条题解
-
0
问题重述
给定一个长度为偶数 的字符串 ,求将其分割成若干子串 ( 为偶数)的方案数,使得子串序列是回文的,即:
答案对 取模。
核心转化
1. 构造新字符串
设 为偶数。定义新字符串 如下:
$$t = s[0]\,s[n-1]\,s[1]\,s[n-2]\,s[2]\,s[n-3] \dots s[n/2-1]\,s[n/2] $$即将 的首尾交替取出,构成新串 。
例如,,:
- , , , , , , ,
- 得到
2. 转化后的等价问题
定理:原问题中 的合法分割与 的偶数长度回文子串分割一一对应。
证明:
设原分割为 ( 为偶数),且满足 。
考虑对称的一对 和 。设 ( 为 的长度),则 相同。
在 中,这两个子串对应的部分为:
这是一个长度为 的回文串(偶数长度)。
由于整个分割是对称的, 会被划分成若干个这样的偶数长度回文子串。
反之,给定 的一个偶数长度回文子串划分,也可以还原出 的一个合法分割。
因此,问题转化为:
求将字符串 分割成若干个偶数长度回文子串的方案数。
动态规划设计
设 表示前缀 的合法分割方案数( 从 到 , 为偶数)。
边界条件
表示空串有一种分割方式。
转移方程
对于 ,如果 是奇数,则无法分成偶数长度回文子串(因为总长度是奇数,而每个子串长度是偶数),所以:
对于偶数 ,考虑最后一段子串 ,它必须是偶数长度回文串。那么:
$$dp[i] = \sum_{\substack{j < i \\ i-j \text{ 为偶数} \\ t[j+1..i] \text{ 是回文}}} dp[j] $$直接枚举所有 的复杂度是 ,不可行。我们需要快速找到所有使得 是回文串的 。
快速求所有回文后缀
对于每个位置 ,我们需要知道所有以 结尾的回文子串的起始位置。
方法一:回文自动机(Eertree)
回文自动机(Eertree)可以在 时间内构建,并维护每个位置的所有回文后缀。具体地:
- 每个节点代表一个回文串
- 通过后缀链接可以遍历所有以当前位置结尾的回文串
对于偶数长度回文串,我们只需要考虑长度为偶数的节点。
设 表示以 结尾的所有偶数长度回文串的起始位置集合,则:
通过 Eertree 可以在 内完成转移,总复杂度 。
方法二:Manacher + 差分优化()
另一种方法是利用 Manacher 算法求出每个位置的最长回文半径,然后通过差分数组快速更新 值。
设 表示以 为中心的最长回文半径(包括中心),则:
- 对于奇数长度回文中心 ,回文半径为 ,对应回文串长度为 (奇数),我们不需要
- 对于偶数长度回文中心 和 之间,回文半径为 ,对应回文串长度为 (偶数)
对于每个偶数长度回文中心,设其覆盖的起始位置为 ,则对于所有满足 的位置,都可以从 转移到 。
这可以用差分数组在 内处理。
算法步骤(基于 Eertree)
- 构造 :根据 交替取首尾字符得到 ,长度为 。
- 构建回文自动机:
- 每个节点存储:长度 ,后缀链接 ,转移边
- 额外维护 指向最近的长度为偶数的回文后缀(或直接判断 是否为偶数)
- 动态规划:
- 初始化
- 遍历 从 到 :
- 如果 为奇数,
- 否则,在回文自动机上沿着后缀链接遍历所有以 结尾的回文串:
- 若当前回文串长度为偶数,设其起始位置为 ,则
- 答案即为
复杂度分析
- 构建 :
- 构建回文自动机:
- 动态规划:每个字符最多访问 个后缀链接(均摊 ),总复杂度
因此总复杂度 ,空间复杂度 。
- 1
信息
- ID
- 6209
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者