2565: 最长双回文串
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
2015.4.25新加数据一组
Source
f[i]为以i为结尾向前最长的回文串,g[i]为以i为起始向后的最长回文串,然后就好了。。。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 200000+5 14 #define maxm 10000+5 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int n,p[maxn],mx,id,f[maxn],g[maxn]; 30 char ch[maxn],st[maxn]; 31 int main(){ 32 //freopen("input.txt","r",stdin); 33 //freopen("output.txt","w",stdout); 34 scanf("%s",ch+1);n=strlen(ch+1); 35 for1(i,n)st[i<<1]=ch[i]; 36 n<<=1;n++; 37 for(int i=1;i<=n;i+=2) 38 st[i]='#'; 39 for(int i=1;i<=n;i++){ 40 if(mx>i)p[i]=min(p[2*id-i],mx-i); 41 while(i-p[i]>0&&i+p[i]<=n&&st[i-p[i]]==st[i+p[i]])p[i]++; 42 if(i+p[i]>mx)mx=i+p[i],id=i; 43 } 44 int ans=0,last=0; 45 for1(i,n) 46 if(i+p[i]>last){ 47 for(int j=last+1;j<i+p[i];j++) 48 if(st[j]!='#')f[j]=j-i+1; 49 last=i+p[i]-1; 50 } 51 last=n+1; 52 for3(i,n,1) 53 if(i-p[i]<last){ 54 for(int j=last-1;j>i-p[i];j--) 55 if(st[j])g[j]=i-j+1; 56 last=i-p[i]+1; 57 } 58 for1(i,n-1)ans=max(ans,f[i]+g[i+2]); 59 printf("%d\n",ans); 60 61 return 0; 62 63 }