caioj1472: 后缀自动机1:多个串的LCS

子串母串跑合并答案

一个点的fail的dep是比任意一条根到这个点路径长度要小的。

那么改就可以直接来了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int len,a[2100];
struct SAM
{
    int w[30],dep,fail;
}ch[2100];int cnt,last;
void insert(int dep,int x)
{
    int pre=last,now=++cnt; ch[now].dep=dep;
    last=now;
    
    while(pre!=0&&ch[pre].w[x]==0)
        ch[pre].w[x]=now, pre=ch[pre].fail;
    if(pre==0)ch[now].fail=1;
    else
    {
        int nxt=ch[pre].w[x];
        if(ch[nxt].dep==ch[pre].dep+1)ch[now].fail=nxt;
        else
        {
            int nnxt=++cnt;
            ch[nnxt]=ch[nxt];
            ch[nnxt].dep=ch[pre].dep+1;
            
            ch[now].fail=ch[nxt].fail=nnxt;
            while(pre!=0&&ch[pre].w[x]==nxt)
                ch[pre].w[x]=nnxt, pre=ch[pre].fail;
        }
    }
}
int Rsort[2100],sa[2100];
void sssort()
{
    for(int i=1;i<=cnt;i++)Rsort[ch[i].dep]++;
    for(int i=1;i<=len;i++)Rsort[i]+=Rsort[i-1];
    for(int i=cnt;i>=1;i--)sa[Rsort[ch[i].dep]--]=i;
}

int f[2100],g[2100];
void solve()
{
    int now=1,L=0;
    memset(f,0,sizeof(f));
    for(int i=1;i<=len;i++)
    {
        int x=a[i];
        while(now!=1&&ch[now].w[x]==0)
            now=ch[now].fail, L=ch[now].dep;
        if(ch[now].w[x]!=0)
        {
            L++;
            now=ch[now].w[x];
            f[now]=max(f[now],L);
        }
    }
    for(int i=cnt;i>=2;i--)
    {
        int x=sa[i],y=ch[sa[i]].fail;
        f[y]=min(ch[y].dep,max(f[y],f[x]));
    }
    
    for(int i=1;i<=cnt;i++)g[i]=min(g[i],f[i]);
}
char ss[2100];
int main()
{
    scanf("%s",ss+1);len=strlen(ss+1);
    cnt=last=1; ch[1].dep=0;
    for(int i=1;i<=len;i++)
        a[i]=ss[i]-'a'+1, insert(i,a[i]);
    sssort();
    
    memset(g,63,sizeof(g));
    while(scanf("%s",ss+1)!=EOF)
    {
        len=strlen(ss+1);
        for(int i=1;i<=len;i++)a[i]=ss[i]-'a'+1;
        solve();
    }
    
    int ans=0;
    for(int i=1;i<=cnt;i++)ans=max(ans,g[i]);
    if(ans<=3)printf("They are too short!\n");
    else printf("True\n%d\n",ans);
    return 0;
}

 

posted @ 2018-12-01 09:39  AKCqhzdy  阅读(237)  评论(0编辑  收藏  举报