[bzoj2938] [Poi2000]病毒

  AC自动机。

  是否存在无限长的不存在非法子串的串。。。也就是询问trie图上有没有不经过非法点的环。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=30023;
 7 int ch[maxn][2],fail[maxn],dl[maxn],tot,next[maxn][2];
 8 bool gg[maxn],u[maxn],ins[maxn],flag;
 9 char s[maxn];
10 int i,j,k,n,m;
11  
12 inline void trie(int n){
13     int now=0,i;
14     for(i=1;i<=n;i++)
15         if(!ch[now][s[i]-48])now=ch[now][s[i]-48]=++tot;
16         else now=ch[now][s[i]-48];
17     gg[now]=1;
18 }
19 inline void getfail(){
20     int l=0,r=1,i,j,p,now;dl[1]=0;
21     while(l<r){
22         now=dl[++l];
23         for(i=0;i<2;i++)if(ch[now][i]){
24             dl[++r]=next[now][i]=j=ch[now][i];
25             for(p=fail[now];p&&!ch[p][i];p=fail[p]);
26             fail[j]=!now?0:ch[p][i];
27             gg[j]|=gg[fail[j]];
28         }else{
29             for(p=fail[now];p&&!ch[p][i];p=fail[p]);
30             next[now][i]=ch[p][i];
31         }
32     }
33 }
34 void dfs(int x){
35     if(ins[x]){flag=1;return;}
36     if(u[x])return;
37     ins[x]=u[x]=1;
38     if(!gg[next[x][0]])dfs(next[x][0]);
39     if(flag)return;
40     if(!gg[next[x][1]])dfs(next[x][1]);
41     ins[x]=0;
42 }
43 int main(){
44     scanf("%d",&n);
45     for(i=1;i<=n;i++)
46         scanf("%s",s+1),trie(strlen(s+1));
47     getfail();
48     dfs(0);
49     puts(flag?"TAK":"NIE");
50 }
View Code

 

posted @ 2016-06-28 09:24  czllgzmzl  阅读(216)  评论(0编辑  收藏  举报