FZU2128_最长子串

题目说给你一个长串,要你选一个最长子串,不包括任何一个给定串为子串。

建立一个自动机,每个点保存的信息为当前这个状态为结尾最长可以有多长?

然后。。。。就可以了。。。

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define maxn 1000100
#define inf 99999999
using namespace std;

char s0[maxn];
char s[105];
int next[100100][26],fail[100100],tag[100100],N;
int n,m,f[maxn],ans;

int add()
{
    N++;
    for (int i=0; i<26; i++) next[N][i]=0;
    tag[N]=inf;
    fail[N]=0;
    return N;
}

void init()
{
    N=-1;
    N=add();
}

void insert()
{
    int cur=0,tep;
    for (int i=0; s[i]; i++)
    {
        tep=s[i]-'a';
        if (next[cur][tep]==0) next[cur][tep]=add();
        cur=next[cur][tep];
    }
    tag[cur]=strlen(s);
}

void AC_build()
{
    int cur,child;
    queue<int> Q;
    Q.push(0);
    while (!Q.empty())
    {
        cur=Q.front(),Q.pop();
        for (int i=0; i<26; i++)
        {
            child=next[cur][i];
            if (child)
            {
                Q.push(child);
                if (cur==0) fail[child]=0;
                else fail[child]=next[fail[cur]][i];
                tag[child]=min(tag[child],tag[fail[child]]);
            }
            else next[cur][i]=next[fail[cur]][i];
        }
    }
}

void query()
{
    ans=0;
    f[0]=1;
    int cur=0,tep;
    for (int i=1; s0[i]; i++)
    {
        f[i]=f[i-1]+1;
        tep=s0[i]-'a';
        cur=next[cur][tep];
        f[i]=min(f[i],tag[cur]);
        ans=max(ans,f[i]);
    }
}

int main()
{
    while (scanf("%s",s0+1)!=EOF)
    {
        init();
        scanf("%d",&n);
        while (n--)
        {
            scanf("%s",s);
            insert();
        }
        AC_build();
        query();
        printf("%d\n",ans-1);
    }
    return 0;
}

 

posted @ 2013-11-20 17:29  092000  阅读(261)  评论(0编辑  收藏  举报