2种思路:
1.枚举前后缀相同尽量长,然后枚举中间的回文串,只要能覆盖前缀或后缀,就记录长度。
2.枚举所有以i为中心的回文串,看回文串前后能否借上前缀或后缀。
枚举回文串用回文树,马拉车,拓展kmp均可。
马拉车。。转化要对应好,好难调。不过下次应该就快了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e6+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y){ee[++cnt].nxt=head[x],ee[cnt].to=y,head[x]=cnt;}
*/
char s[M];
char Ma[M*2];//原串加$后的串
int p[M*2],lMa;//p[i]以i为回文中心的最长回文字串
void init()
{
int ct=0,len=strlen(s);
Ma[ct++]='$';Ma[ct++]='#';
for(int i=0;i<len;i++)
Ma[ct++]=s[i],Ma[ct++]='#';
Ma[ct]=0;
lMa=ct;
}
int manacher()
{
int len=lMa;
int id=0,mx=0;
int ma=0;
for(int i=0;i<len;i++)
{
if(i<mx)p[i]=min(p[2*id-i],mx-i);
else p[i]=1;
while(Ma[i+p[i]]==Ma[i-p[i]])p[i]++;
if(i+p[i]>mx)
mx=p[i]+i,id=i;
ma=max(p[i],ma);
}
return ma-1;
}
bool f[M];
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%s",s);
init();
manacher();
int n=strlen(s);
for(int i=0;i<n;i++)f[i]=false;
for(int i=0;i<n;i++)
{
if(i<=n-i-1&&s[i]==s[n-i-1])f[i]=true;
else break;
}
int ma=0,a,b;
for(int i=0;i<lMa;i++)
{
int l=p[i];
if(l==1&&(Ma[i]=='#'||Ma[i]=='$'))continue;
if(Ma[i]=='#')
{
int tp=i/2-1;//回文串中心的左边字符的id
int le=(l-1)/2;
if((tp-le+1)==0||f[tp-le])//回文串从前面接上
{
int fl=tp-le+1;
int aa=tp+le,bb=max(n-fl,aa+1);
int nl=aa+1+n-bb;
if(nl>ma&&(fl==n-bb))ma=nl,a=aa,b=bb;
}
if(f[n-1-(tp+le+1)]||(tp+le==n-1))//回文串从后面街上
{
int fl=n-1-(tp+le);
int bb=tp-le+1,aa=min(bb-1,fl-1);
int nl=aa+1+n-bb;
if(nl>ma&&fl==aa+1)ma=nl,a=aa,b=bb;
}
}
else
{
int tp=i/2-1;//当前回文串中心字符对应的id 奇数回文串
int le=(l-1)/2;
if((tp-le)==0||f[tp-le-1])//回文串从前面接上
{
int fl=tp-le;
int aa=tp+le,bb=max(aa+1,n-fl);
int nl=aa+1+n-bb;
if(nl>ma&&fl==n-bb)ma=nl,a=aa,b=bb;
}
if(f[n-1-(tp+le+1)]||(tp+le==n-1))//回文串从后面街上
{
int fl=n-1-(tp+le);
int bb=tp-le,aa=min(fl-1,bb-1);
int nl=n-bb+aa+1;
if(nl>ma&&fl==aa+1)ma=nl,a=aa,b=bb;
// cout<<"--- " <<fl<<" "<<nl<<endl;
}
}
// cout<<i<<" "<<p[i]<<" "<<Ma[i]<<" "<<ma<<" "<<a<<" "<<b<<endl;
}
if(ma==0)
cout<<s[0]<<endl;
else
{
// cout<<a<<" "<<b<<endl;
for(int i=0;i<=a;i++)printf("%c",s[i]);
for(int i=b;i<=n-1;i++)printf("%c",s[i]);
puts("");
}
}
return 0;
}