标签:
Time Limit: 1000MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
input | output |
---|---|
ThesampletextthatcouldbereadedthesameinbothordersArozaupalanalapuazorA |
ArozaupalanalapuazorA |
/* * URAL 1297 Palindrome * 求一个字符串的最长回文子串 * * 考虑用后缀数组做,首先在字符串后面加一个不会出现的字符,再将原串反转接到原串的后面, * 得到一个长度为2*len+1的新字符串,求出后缀数组和height数组 * 考虑这个性质,如果一个字符串有回文子串,那么按照上面构造的新字符串的对称部分有相同的前缀 * 这样我们就可以枚举这个回文串的中心字符,然后求出这个位置和对称位置的lcp,这个的两倍就是 * 回文串的长度,根据height数组的性质,lcp(i,j)=min(height[rank[i]+1],....,height[rank[j]]) * 这个是区间最小值,用rmq或者线段树等都可以在O(n*logn)的复杂度内求出来,这样枚举每个位置,再取 * 一个最大值就可以了,当然枚举的回文中心有奇数和偶数之分,都算一下就ok了,这样总的复杂度就是 * O(n*n*logn),就可以ac了。 */ #include <bits/stdc++.h> using namespace std; const int MAXN = 2000+100; int sa[MAXN]; int t1[MAXN],t2[MAXN],c[MAXN]; int Rank[MAXN],height[MAXN]; void build_sa(int s[],int n,int m) { int i,j,p,*x=t1,*y=t2; for(i=0;i<m;i++)c[i]=0; for(i=0;i<n;i++)c[x[i]=s[i]]++; for(i=1;i<m;i++)c[i]+=c[i-1]; for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i; for(j=1;j<=n;j<<=1) { p=0; for(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<m;i++)c[i]=0; for(i=0;i<n;i++)c[x[y[i]]]++; for(i=1;i<m;i++)c[i]+=c[i-1]; for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; if(p>=n)break; m=p; } } void getHeight(int s[],int n) { int i,j,k=0; for(i=0;i<=n;i++) Rank[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[Rank[i]-1]; while(s[i+k]==s[j+k])k++; height[Rank[i]]=k; } } struct SparseTable { int rmq[MAXN]; int mm[MAXN]; int dp[MAXN][20]; void init(int n) { mm[0]=-1; for(int i=1;i<=n;i++) { mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1]; dp[i][0]=i; } for(int j=1;j<=mm[n];j++) for(int i=1;i+(1<<j)-1<=n;i++) dp[i][j]=rmq[dp[i][j-1]]<rmq[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]; } int query(int a,int b) { if(a>b) swap(a,b); int k=mm[b-a+1]; return rmq[dp[a][k]]<=rmq[dp[b-(1<<k)+1][k]]?dp[a][k]:dp[b-(1<<k)+1][k]; } }ST; int lcp(int a,int b) { a=Rank[a],b=Rank[b]; if(a>b) swap(a,b); return height[ST.query(a+1,b)]; } int ss[MAXN]; char str[MAXN]; int main() { scanf("%s",str); int len=strlen(str); int n=2*len+1; for(int i=0;i<len;i++) ss[i]=str[i]; ss[len]=1; for(int i=0;i<len;i++) ss[n-i-1]=str[i]; ss[n]=0; build_sa(ss,n+1,128); getHeight(ss,n); for(int i=1;i<=n;i++) ST.rmq[i]=height[i]; ST.init(n); int st,ans=0; for(int i=0;i<len;i++) { int tmp=lcp(i,n-i); if(2*tmp>ans)//偶对称 { ans=2*tmp; st=i-tmp; } tmp=lcp(i,n-i-1); if(2*tmp-1>ans)//奇对称 { ans=2*tmp-1; st=i-tmp+1; } } str[ans+st]=0; printf("%s\n",str+st); return 0; }
标签:
原文地址:http://www.cnblogs.com/wangdongkai/p/5778278.html