<pre class="cpp" name="code">
斗破苍穹
Time Limit: 1 Sec
Memory Limit: 128 MB
<pre class="cpp" name="code">
Submit: 196 Solved: 42
Submit Status Web Board
Description
有一天, 我们帅气的LC来到加玛帝国. 有时候, 缘分就是这么奇怪, LC和加玛帝国的公主一见钟情, 奈何公主的父王不同意, 因为他觉得LC除了长得特别帅之外, 并没有一技之长.
LC对此呵呵一笑, 他说, 我可是创新实验室走出来的学生, 我会的技能可多着呢, 先说个简单的吧, 只要你给我任意一串字符串, 我就能立马算出这串字符串当中最长回文串的长度. 国王很是吃惊, 说要考一考LC.
于是国王想让你帮忙写一个程序, 用来比对LC的答案, 快来帮帮国王吧!
Input
第一行输入一个T(T <= 50), 表示一共有T组测试数据. 接下来T行, 每行为一组由小写字母组成, 长度不超过10^5的字符串.
Output
每行一个整数X, 表示该组字符串中所包含的最长回文长度.
Sample Input
3aba
abc
aabaa
Sample Output
3
1
5
分析:
最长回文子串模板题,用Manacher算法。时间为O(n)
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
using namespace std;
const int N=200100;
int n,p[N];
char s[N],str[N];
void kp()
{
int i;
int mx=0;
int id;
memset(p,0,sizeof(p));
for(i=n;str[i]!=0;i++)
str[i]=0;
for(i=1;i<n;i++)
{
if(mx>i)
p[i]=min(p[2*id-i],p[id]+id-i);
else p[i]=1;
for(;str[i+p[i]]==str[i-p[i]];p[i]++)
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
}
void init()
{
int i,j,k;
str[0]='$';
str[1]='#';
for(i=0;i<n;i++)
{
str[i*2+2]=s[i];
str[i*2+3]='#';
}
n=n*2+2;
s[n]=0;
}
int main()
{
int i,ans;
int t;
cin>>t;
while(t--)
{
cin>>s;
n=strlen(s);
init();
kp();
ans=0;
for(i=0;i<n;i++)
if(p[i]>ans)
ans=p[i];
cout<<ans-1<<endl;
}
return 0;
}