POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203

来源:互联网 发布:pc微信多开软件 编辑:程序博客网 时间:2024/06/05 15:09

后缀数组的买1送2题。。。

HDU的那题数据实在是太水了,后来才发现在COJ和POJ上都是WA。。原因在一点:在建立sa数组的时候里面的n应该是字符串长度+1.。。。不懂可以去看罗大神的论文。。。

就是利用后缀数组模板求最长公共子串。


#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<cmath>#include<set>#include<vector>#define mem(a,b) memset(a,b,sizeof(a))#define FOR(a,b,i) for(i=a;i<=b;++i)#define For(a,b,i) for(i=a;i<b;++i)#define N 1000000007using namespace std;inline void RD(int &ret){    char c;    do    {        c=getchar();    }    while(c<'0'||c>'9');    ret=c-'0';    while((c=getchar())>='0'&&c<='9')    {        ret=ret*10+(c-'0');    }}inline void OT(int a){    if(a>=10)    {        OT(a/10);    }    putchar(a%10+'0');}char f[2000005];int rank[1000005],sa[1000005],top[1000005],tmp[1000005],height[1000005],wa[1000005],wb[1000005];int cmp(int *r,int a,int b,int l){    return r[a]==r[b]&&r[a+l]==r[b+l];}void makesa(int n)//后缀数组模板{    int i,j,p=0,*t,*x=wa,*y=wb,m=300;    for(i=0; i<m; i++)    {        top[i]=0;    }    for(i=0; i<n; i++)    {        top[x[i]=f[i]]++;    }    for(i=1; i<m; i++)    {        top[i]+=top[i-1];    }    for(i=n-1; i>=0; i--)    {        sa[--top[x[i]]]=i;    }    for(j=1; p<n; j+=j,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++)        {            tmp[i]=x[y[i]];        }        for(i=0; i<m; i++)        {            top[i]=0;        }        for(i=0; i<n; i++)        {            top[tmp[i]]++;        }        for(i=1; i<m; i++)        {            top[i]+=top[i-1];        }        for(i=n-1; i>=0; i--)        {            sa[--top[tmp[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++;        }    }}void makeheight(int n){    int j,i,k;    for(i=1; i<=n; i++)    {        rank[sa[i]]=i;    }    for(i=0,k=0; i<n; height[rank[i++]]=k)    {        for(k?k--:0,j=sa[rank[i]-1]; f[i+k]==f[j+k]; k++);    }}int main(){    int i,l,ll,sum;    while(scanf("%s",f)!=EOF)    {        ll=strlen(f);        l=ll;        f[ll]='&';        scanf("%s",f+l+1);        ll=strlen(f);        makesa(ll+1);//就是这里啊,一语惊醒梦中人        makeheight(ll);        sum=0;        for(i=2;i<ll;++i)        {            if(height[i]>sum)            {                if((sa[i]>l&&sa[i-1]<l)||(sa[i]<l&&sa[i-1]>l))                {                    sum=height[i];                }            }        }        OT(sum);        printf("\n");    }    return 0;}


原创粉丝点击