SPOJ LCS2 Longest Common Substring II ——后缀自动机

后缀自动机裸题

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i<=k;--i)
#define inf 0x3f3f3f3f
#define ll long long
#define maxn 200005 
 
struct sam{
    char s[maxn];
    int h[maxn],to[maxn],ne[maxn],en,ttt;
    int dp[maxn][10],n;
    int last,cnt,len,lth;
    int go[maxn][26],l[maxn],fa[maxn];
    void addedge(int a,int b)
    {to[en]=b;ne[en]=h[a];h[a]=en++;}
    void init()
    {
    	memset(h,-1,sizeof h);en=0;
        last=cnt=1;
//        memset(go,0,sizeof go);
//        memset(dp,0,sizeof dp);
    }
    void add(int x)
    {
//      printf("add %d
",x);
        int p=last,np=last=++cnt; l[np]=l[p]+1;
//      printf("on point %d
",np);
        for (;p&&!go[p][x];p=fa[p]) go[p][x]=np;
        if (!p) fa[np]=1;
        else
        {
            int q=go[p][x];
            if (l[q]==l[p]+1) fa[np]=q;
            else
            {
                int nq=++cnt;
                l[nq]=l[p]+1;
                memcpy(go[nq],go[q],sizeof go[q]);
                fa[nq]=fa[q];
                fa[np]=fa[q]=nq;
                for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
            }
        }
    }
    void dfs(int o)
    {
    	for (int i=h[o];i>=0;i=ne[i])
    	{
    		dfs(to[i]);
    		F(j,1,ttt)
    			dp[o][j]=max(dp[o][j],dp[to[i]][j]);
		}
	}
    void solve()
    {
        scanf("%d",&n);
        scanf("%s",s+1);
        lth=len=strlen(s+1);
        F(i,1,lth) add(s[i]-'a');
        int i=0;
        while (scanf("%s",s+1)!=EOF)
        {
        	++i;
//            scanf("%s",s+1);
            len=strlen(s+1);
            int now=1,t=0;
            F(j,1,len)
            {
                int x=s[j]-'a';
                if (go[now][x]) {t++;now=go[now][x];}
                else
                {
                    while (now&&!go[now][x]) now=fa[now];
                    if (!now) {t=0;now=1;}
                    else t=l[now]+1,now=go[now][x];
                }
                dp[now][i]=max(dp[now][i],t); 
//                for (int k=now;k;k=fa[k]) dp[k][i]=max(dp[k][i],t);
            }
        }
        dfs(1);
        int ans=0;ttt=i;
        F(i,1,cnt) addedge(fa[i],i);
        F(i,1,cnt)
        {
            int tmp=l[i];
            F(j,2,ttt)
                tmp=min(tmp,dp[i][j]);
            ans=max(ans,tmp);
        }
        printf("%d
",ans);
    }
}SAM;
 
int main()
{
    SAM.init();
    SAM.solve();
}

  

原文地址:https://www.cnblogs.com/SfailSth/p/6486947.html