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;
}
如有转载,请注明出处(http://www.cnblogs.com/lochan)