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

后缀数组的买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 1000000007
using 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;
}


 

 

posted @ 2013-08-22 18:23  pangbangb  阅读(196)  评论(0编辑  收藏  举报