题意
输入长度为(n)的串(S),求(S)的最长双回文子串(T),即可将(T)分为两部分(X,Y),((|X|,|Y|≥1))且(X)和(Y)都是回文串。
sol
显然是枚举(X)和(Y)在那个地方断吧。
那么就需要求出位置(i)的最长回文后缀和(i+1)的最长回文前缀,然后拼起来就可以了。
回文后缀可以直接回文树求。
回文前缀?
(reverse)过来再做一遍即可。
code
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e5+5;
struct Palindromic_Tree{
int last,tot,tr[N][26],fa[N],len[N];
void init(){fa[0]=fa[1]=1;len[tot=1]=-1;}
void extend(int c,int n,char *s)
{
int v=last;
while (s[n-len[v]-1]!=s[n]) v=fa[v];
if (!tr[v][c])
{
int u=++tot,k=fa[v];
len[u]=len[v]+2;
while (s[n-len[k]-1]!=s[n]) k=fa[k];
fa[u]=tr[k][c];tr[v][c]=u;
}
last=tr[v][c];
}
}t1,t2;
char s[N];int f[N],g[N];
int main()
{
scanf("%s",s+1);
int n=strlen(s+1),ans=0;
t1.init();t2.init();
for (int i=1;i<=n;++i) t1.extend(s[i]-'a',i,s),f[i]=t1.len[t1.last];
reverse(s+1,s+n+1);
for (int i=1;i<=n;++i) t2.extend(s[i]-'a',i,s),g[n-i+1]=t2.len[t2.last];
for (int i=1;i<n;++i) ans=max(ans,f[i]+g[i+1]);
printf("%d
",ans);return 0;
}