求一个串的最长回文子串
把原串的反串加个原串后面,中间加个没有出现过的字符
然后,原串中,下标i在反串中对应的位置为2*l-i
如果求以i为对称轴的回文串,我们求suffix(i)和suffix(2*l-i)的LCP
如果求以i和i+1为对称轴的回文串,我们求suffix(i+1)和suffix(2*l-i)的LCP
画下就知道了
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2010;
int wa[MAX],wb[MAX],wv[MAX],wn[MAX],a[MAX],sa[MAX];
char s[MAX];
int cmp(int* r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void DA(char* r,int* sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=0; i<m; i++)wn[i]=0;
for(i=0; i<n; i++)wn[x[i]=r[i]]++;
for(i=1; i<m; i++)wn[i]+=wn[i-1];
for(i=n-1; i>=0; i--)sa[--wn[x[i]]]=i;
for(j=1,p=1; p<n; j*=2,m=p)
{
for(p=0,i=n-j; i<n; i++)y[p++]=i;
for(i=0; i<n; i++)if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=0; i<n; i++)wv[i]=x[y[i]];
for(i=0; i<m; i++)wn[i]=0;
for(i=0; i<n; i++)wn[wv[i]]++;
for(i=1; i<m; i++)wn[i]+=wn[i-1];
for(i=n-1; i>=0; i--)sa[--wn[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1; i<n; i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
return;
}
int Rank[MAX],height[MAX],M[MAX][15],l,n;
void calheight(char* r,int* sa,int n)
{
int i,j,k=0;
for(i=1; i<=n; i++)Rank[sa[i]]=i;
for(i=0; i<n; height[Rank[i++]]=k)
for(k?k--:0,j=sa[Rank[i]-1]; r[i+k]==r[j+k]; k++);
return;
}
void RMQ_init()
{
int i,j;
for(i=1;i<=n;i++)
M[i][0]=i;
for(j=1;(1<<j)<=n;j++)
{
for(i=1;i+(1<<j)-1<=n;i++)
{
if(height[M[i][j-1]]<height[M[i+(1<<(j-1))][j-1]])
M[i][j]=M[i][j-1];
else
M[i][j]=M[i+(1<<(j-1))][j-1];
}
}
}
int RMQ(int l,int r)
{
if(l>r)
swap(l,r);
l++;
//cout<<"l="<<l<<" r="<<r;
int t=(int)(log((double)(r-l+1))/log(2.0));
return min(height[M[l][t]],height[M[r-(1<<t)+1][t]]);
}
void solve()
{
int res=0,idx=0,i,j;
for(i=0;i<l;i++)
{
int t=RMQ(Rank[i],Rank[n-i-1]);
if(2*t-1>res)
{
res=2*t-1;
idx=i;
}
//cout<<" t="<<t;
if(s[i]==s[i+1])
{
t=RMQ(Rank[i+1],Rank[n-i-1]);
if(2*t>res)
{
res=2*t;
idx=i;
}
}
//cout<<" t="<<t<<endl;
}
//cout<<"idx="<<idx<<" res="<<res<<endl;
idx=idx-(res-1)/2;
for(j=0;j<res;j++)
printf("%c",s[idx+j]);
puts("");
}
int main()
{
int i,j,k;
while(scanf("%s",s)!=EOF)
{
char c=24;
l=strlen(s);
s[l]=24;
for(i=0;i<l;i++)
{
s[l+i+1]=s[l-i-1];
}
n=2*l+1;
s[n+1]=0;
DA(s,sa,n+1,255);
calheight(s,sa,n);
/*for(i=0;i<=l;i++)
cout<<sa[i]<<" ";
cout<<endl;
for(i=0;i<=l;i++)
cout<<Rank[i]<<" ";
cout<<endl;*/
RMQ_init();
solve();
}
return 0;
}