[SHOI2011]双倍回文 题解
Posted jeefy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SHOI2011]双倍回文 题解相关的知识,希望对你有一定的参考价值。
[SHOI2011]双倍回文 题解
看了一些写回文自动机的大佬的代码,我深感敬畏,于是我转身向Manacher走去
现在荣登最优解第一页……
说实话,这个方法的复杂度是很玄学的,但是加了一些优化之后,就几乎不可能被卡到 \\(O(n^2)\\) 了。
具体思路如下:
预处理字符串部分就略过吧
- 我们预先跑一次 Manacher 算法,考虑到我们其实只需要偶数的回文串的信息,所以将步长设为 2 就行了。
int M(0), R(0), p;
for (int i(1); i < n; i += 2)
p = R > i ? min(R - i + 1, P[(M<<1) - i]) : 1;
while (s[i + p] == s[i - p]) ++p; // 向两边扩展
if (i + p - 1 > R) M = i, R = i + p - 1; // 更新边界
P[i] = p;
-
接着,我们寻找答案。考虑枚举每一个以
i
为中心的偶数回文串。对于这个回文串,我们枚举其回文左区间内的所有点,判断其能否与右区间内对应的区间构成双倍回文即可。换句话来说,假如我们枚举到了j
,那么如果j
是左侧的合法答案,就一定有j + P[j] > i
额,注意一下,这里的
P[i]
指的是回文串的直径,是包括了中间点的元素的。也就是说,回文串所在区间其实是(i - P[i], i + P[i])
(闭区间!)但是,这并不是充要条件。我们考虑这样一种情况
这个时候,
j
其实是不合法的,因为绿色的区间才是合法的区间(合法的区间一定是被i
的回文区间完全包含的!)。所以,对于合法区间的中点,一定在i
的做右区间中点的左边或者右边。那么实际上,我们只需要枚举(i, i + P[i]/2]
作为中点即可。 -
小小的优化:我们需要最大值,所以令答案为
ans
,我们枚举(i + ans, i + P[i]/2]
即可。而且,我们需要的偶数的回文串,所以步长也可以设为 2 来枚举的。
参考代码:
#include <stdio.h>
#define N 1000006
int n, P[N];
char s[N];
inline int min(int x, int y)
return x < y ? x : y;
inline int max(int x, int y)
return x > y ? x : y;
int main()
scanf("%d", &n);
char tmp;
do tmp = getchar(); while (tmp < \'a\');
s[0] = \'^\', s[1] = \'#\', s[2] = tmp, s[3] = \'#\';
for (int i(2); i <= n; ++i)
s[(i<<1)] = getchar(), s[(i<<1)|1] = \'#\';
// printf("%s\\n", s);
int ans(0);
int M(0), R(0), p;
n = (n<<1) + 2;
for (int i(1); i < n; i += 2)
p = R > i ? min(R - i + 1, P[(M<<1) - i]) : 1;
while (s[i + p] == s[i - p]) ++p; // 向两边扩展
if (i + p - 1 > R) M = i, R = i + p - 1; // 更新边界
P[i] = p;
// 寻找答案
for (int i(1); i < n; i += 2)
int p = P[i] / 2 + 1;
for (int r(ans); r < p; r += 2)
if (P[i + r] > r && P[i - r] > r) ans = r;
printf("%d\\n", ans + ans);
return 0;
bzoj2342[Shoi2011]双倍回文
这题属于博主还未填坑系列,先嘴巴AC,到时候有时间再搞字符串时,再来好好填坑。
废话不多说上题:
题解:
显然是和马拉车有关的吧,我们可以先对整个串跑一个马拉车,然后枚举‘#’好字符,并以他为中心,在枚举一个在其回纹半径之内的‘#’号,检查二号#是否能覆盖一号,可以的话显然就是一个双回文了,但他的复杂度是n平方的,所以要优化,优化也不难,
思考一下,就会发现,当一号的回文半径很大时,如果二号#不能覆盖一号#,那么当一号#被更新更向右时,显然也是无法覆盖的
所以路径压缩以下,用并查集来实现。
代码:以后填坑。
以上是关于[SHOI2011]双倍回文 题解的主要内容,如果未能解决你的问题,请参考以下文章