题意:
给了一个字符串...现在要找这样一个字串:设W为一个字符串..Wr为其逆串..现在要找的是WWrWWr...如果存在..输出其最长的长度..否则输出0..
题解:
先用manacher找出每个位置为中点最长的回文串的长度...然后就是枚举了..简单的说WWrWWr一定也是回文的..而WWr又是回文的..那么就是要找长度4倍数的回文串..并且其前后1/4分点又存在长度为回文串长度为原串的1/2...
枚举的时候很多讲究.要不就超时...
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<set>
#include <stack>
#include<queue>
#include<algorithm>
#include<cmath>
#define oo 1000000007
#define ll long long
#define pi acos(-1.0)
#define MAXN 800005
using namespace std;
char str[MAXN],s[MAXN];
int dp[MAXN];
int manacher()
{
int l,i,j,w,p,k,ans=0;
l=strlen(str);
memset(dp,0,sizeof(dp));
s[0]='*';
for (i=0;i<l;i++) s[i*2+1]=str[i],s[i*2+2]='*';
l*=2;
memset(dp,0,sizeof(dp));
dp[0]=ans=1; w=p=0;
for (i=1;i<=l;i++)
{
if (i<=w) dp[i]=dp[2*p-i];
if (i+dp[i]/2>=w)
{
p=i;
if (w>=i) dp[i]=(w-i)*2;
else w=i;
dp[i]++;
while (w+1<=l && s[w+1]==s[2*p-w-1]) dp[i]+=2,w++;
}
ans=max(ans,dp[i]/2);
}
return l;
}
int main()
{
int cases,len,i,l,ans,t;
scanf("%d",&cases);
while (cases--)
{
scanf("%s",str);
len=manacher();
ans=0;
for (i=0;i<=len;i+=2)
if (dp[i]>8)
{
if (dp[i]%8) l=dp[i]-dp[i]%8+1;
else l=dp[i]-7;
for (;l>=ans<<1;l-=8)
{
t=i-l/4;
if (dp[t]<l/2) continue;
t=i+l/4;
if (dp[t]<l/2) continue;
ans=l/2;
}
}
printf("%d\n",ans);
}
return 0;
}