char Ma[N<<1],s[N];
int r[N<<1];
int L[N << 1], R[N << 1];
void Manacher(char s[], int len)
{
int l = 0;
Ma[l++] = '$';
Ma[l++] = '#';
for (int i = 0;i < len;i++)
{
Ma[l++] = s[i];
Ma[l++] = '#';
}
Ma[l] = 0;
int mx = 0, id = 0;
for (int i = 0;i < l;i++)
{
r[i] = mx > i ? min(r[2 * id - i], mx - i) : 1;
while (Ma[i + r[i]] == Ma[i - r[i]])r[i]++;
if (i + r[i] > mx)
{
mx = i +r[i];
id = i;
}
L[i - r[i]+1] = max(L[i - r[i]+1], r[i]-1);
R[i + r[i]-1] = max(R[i + r[i]-1], r[i]-1);
}
}
int main()
{
//freopen("in.txt", "r", stdin);
scanf("%s", s);
int len = strlen(s);
Manacher(s,len);
int mx = 0;
int ans = 0;
int top = len * 2 + 1;
//$#2#1#2#
f(i, 3, top)
{
L[i] = max(L[i], L[i - 2]-2);
i++;
}
ff(i, top-3, 1)
{
R[i] = max(R[i], R[i+2]-2);
i--;
}
f(i, 1, top)
{
if(R[i]&&L[i])//必须两端都有
ans = max(ans, R[i] + L[i]);
i++;
}
cout << ans << endl;
return 0;
}
P4555 [国家集训队]最长双回文串(Manacher,枚举分割点)
最新推荐文章于 2024-01-26 20:14:48 发布