hdu3065 ac自动机


3
AA
BB
CC
ooxxCC%dAAAoen....END
 


Sample Output
AA: 2
CC: 1

重复记录


const  int  maxn = 1000008  ;

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

void  Insert(TrieNode *root , char *s , int id){
      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->id = id ;
}

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  vis[2000008] ;
void ask(TrieNode *root , char *s){
     memset(vis , 0 , sizeof(vis)) ;
     TrieNode *now = root ;
     int sum = 0 , k  ;
     while(*s){
          if(*s >= 'A' && *s <= 'Z'){
              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->id > 0){
                   vis[f->id]++ ;
                   f = f->fail ;
              }
          }
          else  now = root ;
          s++ ;
     }
}

char word[1008][58] ;
char text[2000008] ;

int  main(){
     int n , m  , i  ;
     while(cin>>n){
          TrieNode *root = new TrieNode() ;
          for(i = 1 ; i <= n ; i++){
              scanf("%s" ,  word[i]) ;
              Insert(root , word[i] , i) ;
          }
          makeAC(root) ;
          scanf("%s" , text) ;
          ask(root , text) ;
          for(i = 1 ; i <= n ; i++){
              if(vis[i] > 0)
                  printf("%s: %d\n" , word[i] , vis[i]) ;
          }
     }
     return 0 ;
}

char  word[1008][58] ;
char  text[2000008] ;

/*AC-------------*/
const  int maxn = 1000*58 ;
const  int kind = 128 ;
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 < kind ; i++) next[n][i] = -1 ;
             return n++ ;
        }
        void  Init(){
              n = 0 ;
              root = newnode() ;
        }
        void  Insert(char *s , int idx){
              int now = root  , k ;
              while(*s){
                   k = *s - ' ' ;
                   if(next[now][k] == -1)
                       next[now][k] = newnode() ;
                   now = next[now][k] ;
                   s++ ;
              }
              id[now] = idx  ;
        }
        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  vis[1008] ;
        void ask(char *s , int m){
             memset(vis , 0 , sizeof(vis)) ;
             int now = root , k  ;
             while(*s){
                  k = *s - ' ' ;
                  now = next[now][k] ;
                  int t = now  ;
                  while(t != root){
                       vis[id[t]]++ ;
                       t = fail[t] ;
                  }
                  s++ ;
             }
             for(int i = 1 ; i <= m ; i++){
                  if(vis[i]) printf("%s: %d\n" , word[i] , vis[i]) ;
             }
        }
}ac ;
/*EndAc---------------*/

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





你可能感兴趣的:(hdu3065 ac自动机)