题目链接:http://openoj.awaysoft.com/JudgeOnline/problem.php?id=1897
题意:给出一个串s和一些病毒串。求s的最长不包含病毒的子串。
思路:将病毒串建立自动机,节点保存深度,深度初始化无穷大。每次出现 病毒串的时候从病毒串的第二个位置开始重新计数。
struct node
{
int next[26],fail,len;
void init()
{
clr(next,0);
fail=0;
len=INF;
}
};
node a[N];
int e;
void insert(char s[])
{
int i,k,p=0;
for(i=0;s[i];i++)
{
k=s[i]-'A';
if(a[p].next[k]==0)
{
a[e].init();
a[p].next[k]=e++;
}
p=a[p].next[k];
}
a[p].len=i;
}
queue<int> Q;
void build()
{
int i,j,k,p,q;
FOR0(i,26) if(a[0].next[i]) Q.push(a[0].next[i]);
while(!Q.empty())
{
k=Q.front();
Q.pop();
for(i=0;i<26;i++)
{
if(a[k].next[i])
{
p=a[k].next[i];
q=a[k].fail;
Q.push(p);
a[p].fail=a[q].next[i];
a[p].len=min(a[p].len,a[a[p].fail].len);
}
else
{
q=a[k].fail;
a[k].next[i]=a[q].next[i];
}
}
}
}
int C;
int n,m;
char s[N],s1[N];
int main()
{
RD(C);
while(C--)
{
a[0].init();e=1;
RD(n,m); RD(s);
while(m--) RD(s1),insert(s1);
build();
int ans=0,t=0,i,j,k,L=0;
FOR0(i,n)
{
k=s[i]-'A';
t=a[t].next[k];
j=i+1-a[t].len;
if(j>=L) L=j+1;
else ans=max(ans,i+1-L);
}
PR(ans);
}
return 0;
}