BZOJ2565:最长双回文串
Posted QYP_2002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ2565:最长双回文串相关的知识,希望对你有一定的参考价值。
2565: 最长双回文串
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2195 Solved: 1119
[Submit][Status][Discuss]
Description
顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。
输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。
Input
一行由小写英文字母组成的字符串S。
Output
一行一个整数,表示最长双回文子串的长度。
Sample Input
baacaabbacabb
Sample Output
12
HINT
样例说明
从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。
对于100%的数据,2≤|S|≤10^5
思路{
首先应该建出回文自动机,那么我们可以很自然地想到在插入字符的过程中统计当前插入的字符的长度(因为回文自动机保证了当前插入的字符串是能匹配的最长长度)。
但是还要反向搞一下即可。
}
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define inf (1<<30) #define il inline #define RG register #define LL long long #define maxx 100010 using namespace std;char s[maxx]; int nxt[maxx][27],len[maxx],f[maxx],l,cc,Maxpre[maxx],Maxnxt[maxx]; void Insert(int n,int c,int p[]){ int P=l;while(s[n-len[P]-1]!=s[n])P=f[P]; if(!nxt[P][c]){ len[++cc]=len[P]+2; int p=f[P]; while(s[n-len[p]-1]!=s[n])p=f[p]; f[cc]=nxt[p][c],nxt[P][c]=cc; }l=nxt[P][c];p[n]=len[l]; }char t[maxx]; void work(){ f[0]=1,len[++cc]=-1; scanf("%s",s+1);int L=strlen(s+1); for(RG int i=1;i<=L;++i)Insert(i,s[i]-‘a‘,Maxpre);l=cc=0; memset(nxt,0,sizeof(nxt));memset(len,0,sizeof(len));memset(f,0,sizeof(f)); f[0]=1,len[++cc]=-1; for(RG int i=1;i<=L;++i)t[L-i+1]=s[i];for(int i=1;i<=L;++i)s[i]=t[i]; for(RG int i=1;i<=L;++i)Insert(i,s[i]-‘a‘,Maxnxt);LL Ans=0; for(RG int i=1;i<=L;++i)Ans=max(Ans,(LL)Maxnxt[i]+Maxpre[L-i]);printf("%lld",Ans); } int main(){ freopen("1.in","r",stdin); // freopen("1.out","w",stdout); work();return 0; }
以上是关于BZOJ2565:最长双回文串的主要内容,如果未能解决你的问题,请参考以下文章