ural1297 Palindrome【后缀数组】

来源:互联网 发布:excel表格对比两列数据 编辑:程序博客网 时间:2024/06/04 18:43

题意:给出一个串,求出这个串的最长回文字串。

用后缀数组解决,把这个串反向并接在原串后面,中间加一个没有出现过的字符。然后枚举回文字串的中心(这里要按串的长度分成奇数长度和偶数长度),求这个枚举的位置和在反向接上去的那个位置,这两个位置之间的最长公共前缀就可以了。。求公共前缀用个线段树维护就好了

#include<cstdio>#include<cstring>#include<algorithm>#define ls (k<<1)#define rs (k<<1|1)using namespace std;const int MAXN=2010;int wa[MAXN],wb[MAXN],ws[MAXN],wv[MAXN];bool cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];}void da(int *r,int *sa,int n,int m){int i,j,p,*x=wa,*y=wb;for(i=0;i<m;i++)ws[i]=0;for(i=0;i<n;i++)ws[x[i]=r[i]]++;for(i=1;i<m;i++)ws[i]+=ws[i-1];for(i=n-1;i>=0;i--)sa[--ws[x[i]]]=i;p=1;for(j=1;p<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<n;i++)wv[i]=x[y[i]];for(i=0;i<m;i++)ws[i]=0;for(i=0;i<n;i++)ws[wv[i]]++;for(i=1;i<m;i++)ws[i]+=ws[i-1];for(i=n-1;i>=0;i--)sa[--ws[wv[i]]]=y[i];swap(x,y);p=1;x[sa[0]]=0;for(i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++;m=p;}}int height[MAXN],RANK[MAXN];void calheight(int *r,int *sa,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(r[i+k]==r[j+k])k++;height[RANK[i]]=k;}}struct TREE{int l,r;int val;int mid(){return (l+r)>>1;}}tree[MAXN<<2];void pushup(int k){tree[k].val=min(tree[ls].val,tree[rs].val);}void build(int l,int r,int k){tree[k].l=l;tree[k].r=r;if(l==r){tree[k].val=height[l];return;}int mid=tree[k].mid();build(l,mid,ls);build(mid+1,r,rs);pushup(k);}int query(int l,int r,int k){if(l>r)return 1;if(tree[k].l>=l&&tree[k].r<=r)return tree[k].val;int mid=tree[k].mid();if(r<=mid)return query(l,r,ls);else if(l>mid)return query(l,r,rs);elsereturn min(query(l,mid,ls),query(mid+1,r,rs));}int r[MAXN],sa[MAXN];char str[MAXN];int main(){int i,n;while(scanf("%s",str)==1){n=strlen(str);for(i=0;i<n;i++)r[i]=str[i];r[n]='$';for(i=n+1;i<=2*n;i++){r[i]=str[2*n-i];}r[2*n+1]=0;da(r,sa,2*n+2,129);calheight(r,sa,2*n+1);build(1,2*n+1,1);int ans=-2,l,rr,w,u,v;for(i=0;i<n;i++){if(i==59)i=59;u=min(RANK[i],RANK[2*n-i]);v=max(RANK[i],RANK[2*n-i]);int temp=query(u+1,v,1);w=temp*2-1;if (w>ans){ans=w;l=i-temp+1;rr=i+temp-1;}u=min(RANK[i],RANK[2*n-i+1]);v=max(RANK[i],RANK[2*n-i+1]);temp=query(u+1,v,1);w=temp*2;if (w>ans){ans=w;l=i-temp;rr=i+temp-1;}}for(i=l;i<=rr;i++)printf("%c",str[i]);printf("\n");}return 0;}/*ThesampletextthatcouldbereadedthesameinbothordersArozaupalannalapuazorA*/


0 0
原创粉丝点击