题目链接: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; }