您的位置:首页 > 其它

最长回文子串(ural1297)

2010-09-07 09:32 281 查看
解决回文类问题 。 转化为后缀数组的方法是自己想到的 这个还是比较不错。

虽然 $符号的设置是看了以下解题报告。不过 具体用法是自己想到的再接再厉哦 。

这道题算是打补丁 打过去的,开始是没有注意 用求 公共祖先来求得最长匹配串(这里是rmq问题,写成了求h最大,应该是求h数组u最小)。然后是奇数串 和偶数串也有所不同。

然后求最先情况也没有 处理好 。思路一定要清晰,要想好。不然会浪费很多时间。

贴代码以后总结成为模板

#include<iostream>

#include<cstdio>

#include<string.h>

using namespace std;

#define e 40100

int a[e],sa[e],container[e],wy[e],wv[e],wx[e],rrank[e],h[e];

char b[e];

int cmp(int *r,int a,int b,int l)

{

return (r[a]==r[b])&&(r[a+l]==r[b+l]);

}

void suffix(int *r,int n,int *sa,int m)

{

int i,j,*t,*x=wx, *y=wy,p;

memset(container,0,sizeof(int)*m);

for(i=0; i<n; i++) container[x[i]=r[i]]++;

for(i=1; i<m; i++) container[i]+=container[i-1];

for(i=n-1; i>=0; i--) sa[--container[x[i]]]=i;

for(p=0,j=1; p<n; j<<=1,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]];

memset(container,0,sizeof(int)*m);

for(i=0; i<n; i++) container[wv[i]]++;

for(i=1; i<m; i++) container[i]+=container[i-1];

for(i=n-1; i>=0; i--) sa[--container[wv[i]]]=y[i];

for(t=x,x=y,y=t,x[sa[0]]=0,p=1, i=1; i<n; i++)

x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++;

}

}

void cal(int *r,int *sa,int n)

{

int i,j,k=0;

for(i=1; i<=n; i++) rrank[sa[i]]=i;

for(i=0; i<n; h[rrank[i++]]=k)

for(k?k--:0,j=sa[rrank[i]-1]; r[i+k]==r[j+k]; k++);

}

int fmax[e][20];

void makermq(int n)//rmq 问题模板

{

int i,j,k;

for(i=1; i<=n; i++) fmax[i][0]=h[i];

for(j=1; (1<<j)<=n; j++)

{

k=1<<(j-1);

for(i=1; i+k<=n ;i++)

{

fmax[i][j]=min(fmax[i][j-1],fmax[i+k][j-1]);

}

}

}

int findmax(int l,int r)//查找rmq问题模板

{

int k=1;

if(l>r)swap(l,r);

l++;

int dis=r-l+1;

for(k=0; (1<<k)<=dis; k++);

k--;

int x=fmax[l][k];

if(fmax[r-(1<<k)+1][k]<=x)return fmax[r-(1<<k)+1][k];

return x;

}

int main()

{

#ifndef ONLINE_JUDGE

freopen("//home//mabodx//桌面//in.txt","r",stdin);

#endif

int n;int i;

while(cin>>b)

{

n=strlen(b);

int len= n*2;

for(i=0; i<n; i++)

{

a[i]=a[len-i]=b[i];

}

a
=1;//////////////////////////////////这个字符要怎么处理

len++;

a[len]=0;

suffix(a,len+1,sa,301);

cal(a,sa,len);

makermq(len);

int maxx=-1;

int q,r;int j;int flag=1;

int ll=-1;

for(i=0; i< n ;i++)

{

r=findmax(rrank[i],rrank[2*n-i])-1;

if(ll<r*2+1)

{

ll=r*2+1;

maxx=r;

flag=1;

q=i;

}

r=findmax(rrank[i],rrank[2*n-i+1]);

if(ll<r*2)

{

ll=r*2;

maxx=r;

flag=2;

q=i;

}

}

if(flag==1)

{

for(i=q-maxx,j=0;j<maxx*2+1; j++,i++ )

printf("%c",b[i]);cout<<endl;

}

else

{

for(i=q-maxx,j=0; j<maxx*2; j++,i++)

printf("%c",b[i]);cout<<endl;

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: