BZOJ2938 POI2000 病毒 补全AC自动机 Trie图判环

来源:互联网 发布:增值税发票扫描软件 编辑:程序博客网 时间:2024/05/22 00:11

大家都太强了辣,和我这样的大蒟蒻共勉吼不吼啊 ?

题意:
  给您一堆01串,问是否可以构造一个无限长的字符串,使得这些01串都不是她的子串。

题解:

  补全AC自动机判环(不走以单词结尾的点(不止是它本身)),记得加一个优化,就是搜过了没有答案了就continue;
  然后就是简单的DFS判环。

/**************************************************************    Problem: 2938    User: Lazer2001    Language: C++    Result: Accepted    Time:64 ms    Memory:5980 kb****************************************************************/# include <bits/stdc++.h># define N 300010class AhoCrasickAutoMaton  {    private :        bool ban [N], in [N], visited [N] ;        int go [N] [2], fail [N], ncnt ;    public :        inline void insert ( char* s )  {            int cur = 0 ;            for ( char* pt = s ; *pt ; ++ pt )  {                if ( ! go [cur] [*pt - '0'] )  go [cur] [*pt - '0'] = ++ ncnt ;                cur = go [cur] [*pt - '0'] ;            }            ban [cur] = 1 ;        }        void build ( )  {            fail [0] = -1 ;            static std :: queue < int > Q ;            for ( int i = 0 ; i < 2 ; ++ i )  Q.push ( go [0] [i] ) ;            while ( ! Q.empty ( ) )  {                int cur = Q.front ( ) ; Q.pop ( ) ;                for ( int i = 0 ; i < 2 ; ++ i )  {                    if ( go [cur] [i] )  {                        fail [go [cur] [i]] = go [fail [cur]] [i] ;                        Q.push ( go [cur] [i] ) ;                    }  else  {                        go [cur] [i] = go [fail [cur]] [i] ;                    }                }                ban [cur] |= ban [fail [cur]] ;            }        }        inline bool Dfs ( int cur )  {            in [cur] = 1 ;            for ( int i = 0 ; i < 2 ; ++ i )  {                int& v = go [cur] [i] ;                if ( in [v] )  return 1 ;                if ( ban [v] || visited [v] )  continue ;                if ( Dfs ( v ) )  return 1 ;                visited [v] = 1 ; // advanced : if there is no answer, we do not visit it anymore.            }            return in [cur] = 0, 0 ;        }} Ac ;int main ( )  {    int T ;    scanf ( "%d", & T ) ;    while ( T -- )  {        static char s [N] ;        scanf ( "%s", s ) ;        Ac.insert ( s ) ;    }    Ac.build ( ) ;    puts ( Ac.Dfs ( 0 ) ? "TAK" : "NIE" ) ;    return 0 ;}
原创粉丝点击