BZOJ2938 POI2000 Virus Completion AC Auto Trie Graph Ring

Everyone is so hot and strong that they bark and growl with a big burdock like me?

Topic:
_Give you a stack of 01 strings and ask if you can construct an infinite length of strings so that none of them are her substrings.

Questions:

_Complete the AC auto judgment loop (don't go to the point that ends with a word (not just itself), remember to add an optimization, that is, continue after searching for no answer;
_is then a simple DFS ring.

/**************************************************************
    Problem: 2938
    User: Lazer2001
    Language: C++
    Result: Accepted
    Time:64 ms
    Memory:5980 kb
****************************************************************/

# include <bits/stdc++.h>

# define N 300010

class 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 ;
}

Posted by RonHam on Sun, 14 Jun 2020 09:24:20 -0700