zoukankan      html  css  js  c++  java
  • 【AC自动机】病毒

    【题目链接】

    https://loj.ac/problem/10062

    【题意】

    寻找一个没有模式串为子串的无限01串。是否存在。

    【题解】

    其实就是用dfs找一个环。

    1、环需要从根结点出发找到这个位置。且重新能走到这里,我们开一个“预测路径”的数组进行标记即可。

    2、如果下一个结点碰上了“走过”标记过的,而不是“预测路径”,或者是模式串结尾,我们就避开不走。

    注意:

    fail数组是可以进行传递的,就是说fail指向的结点,同时是模式串的结尾,那么该位置也是不合法的。

    最后看看代码怎么实现就明白了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 const int N = 2005;
     8 const int M = 30005;
     9 
    10 int Trie[M][2] , fail[M] , End[M], idx ;
    11 int Q[M] , Head , Tail ;
    12 int vis[M],used[M];
    13 int n ;
    14 
    15 char str[N];
    16 
    17 void Insert( char s[] ){
    18     int p = 0;
    19     for(int i=0 ; s[i] ; i++ ){
    20         int t = s[i] - '0' ;
    21         if( !Trie[p][t] )
    22             Trie[p][t] = ++idx ;
    23         p = Trie[p][t];
    24     }
    25     End[p] ++ ;
    26 }
    27 
    28 void Build(){
    29     Head = 1 , Tail = 0 ;
    30     for(int i=0;i<2;i++)
    31         if(Trie[0][i])
    32             Q[++Tail] = Trie[0][i] ;
    33         //fail[Trie[0][i]] = 0;
    34 
    35     while( Head <= Tail ){
    36         int u = Q[Head++] ;
    37         for(int i=0;i<2;i++){
    38             int To = Trie[u][i];
    39             if( To ){
    40                 fail[To] = Trie[fail[u]][i];
    41                 Q[++Tail] = To;
    42 
    43                 End[To] = End[To] || End[fail[To]] ;
    44             }else{
    45                 Trie[u][i] = Trie[fail[u]][i];
    46             }
    47         }
    48     }
    49 
    50 }
    51 
    52 bool dfs(int u){
    53     vis[u] = 1;
    54     for(int i=0;i<=1;i++){
    55         int To = Trie[u][i];
    56         if( vis[To] ) return true;
    57         if( used[To] || End[To] ) continue;
    58         used[To] = 1 ;
    59         if( dfs(To) ) return true ;
    60     }
    61     vis[u] = 0;
    62     return false ;
    63 }
    64 int main()
    65 {
    66     scanf("%d",&n);
    67     for(int i=0;i<n;i++){
    68         scanf("%s",str);
    69         Insert(str);
    70     }
    71     Build();
    72     puts(dfs(0)?"TAK":"NIE");
    73 
    74     return 0 ;
    75 }
    病毒
  • 相关阅读:
    InSAR 大气校正数据 GACOS
    java通用的方法整理
    Jquery实现select左右栏的添加移除
    kendo ui之grid列表
    kendo-ui学习笔记(一)
    kendo-ui学习笔记——题记
    chrome driver驱动地址
    适合引入缓存的业务及影响
    个人测试方法论202108
    Redis缓存
  • 原文地址:https://www.cnblogs.com/Osea/p/11367032.html
Copyright © 2011-2022 走看看