manacher算法用于计算最长回文子串。
上模板
//s是原子符串,而w是在s的前面、后面、字符之间插入一个未出现的字符‘#’
scanf("%s",s);
w[0]='*';//防止越界,在最前面加上一个‘*’
w[++len]='#';
for(int tmp=strlen(s), i=0;i<tmp;++i)
{
w[++len]=s[i];
w[++len]='#';
}
--len;
//p[i]表示以i为中心向左右扩展的最长回文子串的长度
p[1]=ans=maxd=1;
for(int i=2;i<len;++i)
{
if(p[maxd]+maxd>i)p[i]=min(p[maxd+maxd-i],maxd+p[maxd]-i);
else p[i]=1;
while(w[i+p[i]]==w[i-p[i]])++p[i];
if(ans<p[i])ans=p[i];
if(maxd+p[maxd]<p[i]+i)maxd=i;
}
printf("%d\n",ans-1);
而HDU3294,URAL1297为manacher的裸题。
URAL1297:
题意:求一个字符串的最长回文子串
#include <cstdio>
#include <cstring>
#define MAXN 100005
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
char s[MAXN], a, w[MAXN];
int len, p[MAXN], maxd, ans;
int main()
{
//freopen("data.txt","r",stdin);
scanf("%s",w);
s[0]='*', s[++len]='#';
for(int tmp=strlen(w), i=0;i<=tmp;++i)
{
s[++len]=w[i];
s[++len]='#';
}
--len;
p[1]=ans=1, maxd=1;
for(int i=2;i<len;++i)
{
if(p[maxd]+maxd>i)p[i]=min(p[maxd+maxd-i],p[maxd]-i+maxd);
else p[i]=1;
while(s[i+p[i]]==s[i-p[i]])++p[i];
if(p[maxd]+maxd<p[i]+i)maxd=i;
if(p[ans]<p[i])ans=i;
}
for(int i=ans-p[ans]+1, tmp=p[ans]-1;i<len&&tmp;++i)
{
if(s[i]=='#')continue;
printf("%c",s[i]);
--tmp;
}
return 0;
}
HDU3294:
题目链接
题意:将某一字符串先向左平移若干个单位(第一个字符-‘a’)。求最先出现的最长回文子串的起始位置、结束位置,并输出。
一开始以为第一个字符只会是’a’或’b’,然后就wa了几遍…
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 400050
using namespace std;
char ask[5], s[MAXN], w[MAXN];
int len, p[MAXN], ans, maxd;
int main()
{
while(~scanf("%s",ask))
{
len=0;
scanf("%s",s);
w[0]='*';
w[++len]='#';
for(int tmp=strlen(s), i=0;i<=tmp;++i)
{
w[++len]=s[i];
w[++len]='#';
}
len-=2;
p[1]=ans=1, maxd=1;
for(int i=2;i<len;++i)
{
if(p[maxd]+maxd>i)p[i]=min(p[maxd+maxd-i],p[maxd]+maxd-i);
else p[i]=1;
while(w[i+p[i]]==w[i-p[i]])++p[i];
if(p[i]+i>p[maxd]+maxd)maxd=i;
if(p[ans]<p[i])ans=i;
}
if(p[ans]<3)puts("No solution!");
else
{
int Begin=(ans-p[ans]+2)/2-1, End=(ans+p[ans]-2)/2-1, k=ask[0]-'a';
printf("%d %d\n",Begin,End);
for(;Begin<=End;++Begin)
printf("%c",(s[Begin]-'a'-k+26)%26+'a');
puts("");
}
}
return 0;
}