HYSBZ - 2565
Description
顺序和逆序读起来完全一样的串叫做回文串。比如
acbca
是回文串,而
abc
不是(
abc
的顺序为
“abc”
,逆序为
“cba”
,不相同)。
输入长度为 n 的串 S ,求 S 的最长双回文子串 T, 即可将 T 分为两部分 X , Y ,( |X|,|Y|≥1 )且 X 和 Y 都是回文串。 Input 一行由小写英文字母组成的字符串S。 Output
一行一个整数,表示最长双回文子串的长度。
Sample Input baacaabbacabb Sample Output 12 Hint 样例说明 2015.4.25新加数据一组 Source |
倒着顺着来一遍
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
#define N 26
struct Palindromic_Tree {
int next[MAXN][N];
int fail[MAXN], cnt[MAXN], len[MAXN],num[MAXN],S[MAXN];
int n,p,last;
int newnode(int l)
{
for(int i = 0; i < N; ++i) next[p][i] = 0;
cnt[p] = 0;
num[p] = 0;
len[p] = l;
return p++;
}
void init()
{
last = n = p = 0;
newnode(0);
newnode(-1);
S[0] = -1;
fail[0] = 1;
fail[1] = 0;
}
int get_fail(int x)
{
while(S[n-len[x]-1] != S[n]) x = fail[x];
return x;
}
int add(int c) ///返回新添加的节点
{
c -= 'a';
S[++n] = c;
int cur = get_fail(last);
if(!next[cur][c]) {
int now = newnode(len[cur]+2);
fail[now] = next[get_fail(fail[cur])][c];
next[cur][c] = now;
num[now] = num[fail[now]] + 1;
}
last = next[cur][c];
++cnt[last];
return last;
}
void count()
{
for(int i = p-1; i >= 0; --i) cnt[fail[i]] += cnt[i];
}
};
Palindromic_Tree T;
int len[MAXN];
char s[MAXN];
int main()
{
while(scanf("%s",s+1)==1) {
T.init();
int n = strlen(s+1);
for(int i = n; i >= 1; --i)len[i] = T.len[T.add(s[i])];
int ans = 0;
T.init();
for(int i = 1; i < n; ++i) ans = max(ans,len[i+1]+T.len[T.add(s[i])]);
printf("%d\n",ans);
}
return 0;
}