HDU 2222 AC自动机模板

很好的入门资料,看了绝对懂

点击打开链接

const  int  maxn = 500008  ;

struct  TrieNode{
        TrieNode *fail ;
        TrieNode *next[26] ;
        int cnt ;
        TrieNode(){
             fail = NULL ;
             cnt = 0 ;
             for(int i = 0 ; i < 26 ; i++) next[i] = NULL ;
        }
};

void  Insert(TrieNode *root , char *s){
      TrieNode *now = root ;
      while(*s){
           int k = *s - 'a' ;
           if(now->next[k] == NULL)
                now->next[k] = new TrieNode() ;
           now = now->next[k] ;
           s++ ;
      }
      now->cnt++ ;
}

TrieNode *que[maxn] ;
void  makeAC(TrieNode *root){
      int head = 0  , tail = -1 ;
      que[++tail] =  root ;
      while(head <= tail){
            TrieNode *now = que[head++] ;
            for(int i = 0 ; i < 26 ; i++){
                if(now->next[i] != NULL){
                    if(now == root)
                       now->next[i]->fail = root ;
                    else{
                        TrieNode *f = now->fail ;
                        while(f != NULL){
                            if(f->next[i] != NULL){
                                now->next[i]->fail = f->next[i] ;
                                break ;
                            }
                            f = f->fail ;
                        }
                        if(f == NULL)
                             now->next[i]->fail = root ;
                    }
                    que[++tail] = now->next[i] ;
                }
            }
      }
}

int  ask(TrieNode *root , char *s){
     TrieNode *now = root ;
     int ans = 0  , k ;
     while(*s){
          k = *s - 'a' ;
          while(now != root && now->next[k] == NULL)
              now = now->fail ;
          now = now->next[k] ;
          if(now == NULL) now = root ;
          TrieNode *f = now ;
          while(f != root && f->cnt != -1){
               ans += f->cnt ;
               f->cnt = -1 ;
               f = f->fail ;
          }
          s++ ;
     }
     return ans  ;
}

char  word[58] ;
char  text[1000008] ;

int  main(){
     int i , j , t , n ;
     cin>>t ;
     while(t--){
          scanf("%d" , &n) ;
          TrieNode *root = new TrieNode() ;
          while(n--){
               scanf("%s" , word) ;
               Insert(root , word) ;
          }
          makeAC(root) ;
          scanf("%s" , text) ;
          printf("%d\n" , ask(root , text)) ;
     }
     return 0 ;
}


/*AC-------------*/
const  int maxn = 500008 ;
const  int kind = 26 ;
int    next[maxn][kind] ;
int    fail[maxn] ;
int    id[maxn]   ;

struct  AC{
        int  root , n ;
        int  newnode(){
             id[n] = 0 ;
             for(int i = 0 ; i < 26 ; i++) next[n][i] = -1 ;
             return n++ ;
        }
        void  Init(){
              n = 0 ;
              root = newnode() ;
        }
        void  Insert(char *s){
              int now = root  , k ;
              while(*s){
                   k = *s - 'a' ;
                   if(next[now][k] == -1)
                       next[now][k] = newnode() ;
                   now = next[now][k] ;
                   s++ ;
              }
              id[now]++ ;
        }
        void  makeAc(){
              queue<int> q ;
              fail[root] = root ;
              int now , i ;
              for(i = 0 ; i < kind ; i++){
                   if(next[root][i] == -1)
                       next[root][i] = root ;
                   else{
                       fail[next[root][i]] =  root ;
                       q.push(next[root][i]) ;
                   }
              }
              while(! q.empty()){
                   now = q.front() ; q.pop() ;
                   for(i = 0 ; i < kind ; i++){
                       if(next[now][i] == -1)
                           next[now][i] = next[fail[now]][i] ;
                       else{
                           fail[next[now][i]] = next[fail[now]][i] ;
                           q.push(next[now][i]) ;
                       }
                   }
              }
        }
        int  ask(char *s){
             int now = root , k  , sum = 0 ;
             while(*s){
                  k = *s - 'a' ;
                  now = next[now][k] ;
                  int t = now  ;
                  while(t != root){
                       sum += id[t] ;
                       id[t] = 0 ;
                       t = fail[t] ;
                  }
                  s++ ;
             }
             return sum ;
        }
}ac ;
/*EndAc---------------*/

char  word[58] ;
char  text[1000008] ;

int   main(){
      int t , n  , i ;
      cin>>t ;
      while(t--){
           cin>>n ;
           ac.Init() ;
           for(i = 1 ; i <= n ; i++){
                scanf("%s" , word) ;
                ac.Insert(word) ;
           }
           ac.makeAc() ;
           scanf("%s" , text) ;
           printf("%d\n" , ac.ask(text)) ;
      }
      return 0 ;
}





你可能感兴趣的:(HDU 2222 AC自动机模板)