zoj3430ac自动机

动态存储ME

int   lis[3000] ;

/*AC------------*/
int   next[520*64][256] ;
int   fail[520*64] ;
int   id[520*64] ;
struct  AC{
    int   root , n ;
    int   newnode(){
          for(int i = 0 ; i < 256 ; i++) next[n][i] = -1 ;
          id[n++] = -1 ;
          return n-1 ;
    }
    void  init(){
          n = 0 ;
          root = newnode() ;
    }
    void  insert(int lissize , int idx){
          int now = root , k ;
          for(int i = 0 ; i < lissize ; i++){
               k = lis[i] ;
               if(next[now][k] == -1)
                   next[now][k] = newnode() ;
               now = next[now][k] ;
          }
          id[now] = idx ;
    }
    void  makeAC(){
          queue<int>q ;
          fail[root] = root ;
          int i , now ;
          for(int i = 0 ; i < 256 ; 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 < 256 ; 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]) ;
                   }
               }
          }
    }
    bool vis[520] ;
    int  ask(int lissize , int wordsize){
         memset(vis , 0 , sizeof(vis)) ;
         int now = root , k  , t ;
         for(int i = 0 ; i < lissize ; i++){
             k = lis[i] ;
             now = next[now][k] ;
             t = now ;
             while(t != root){
                 if(id[t] != -1) vis[id[t]] = 1 ;
                 t = fail[t] ;
             }
         }
         int sum = 0 ;
         for(int i = 1 ; i <= wordsize ; i++){
              if(vis[i]) sum++ ;
         }
         return sum ;
    }
}ac ;
/*EndAC---------*/

int  to(char c){
     if('A' <= c && c <= 'Z') return c - 'A' ;
     else if('a' <= c && c <= 'z') return c - 'a' + 26;
     else if('0' <= c && c <= '9') return c - '0' + 52;
     else if(c == '+') return 62 ;
     else return 63 ;
}

int  bit[300000] ;
int  encode(char *s){
     int i , j , x  , t = 0  ;
     int lisszie = 0 ;
     while(*s){
          if(*s != '='){
               x = to(*s) ;
               for(i = 5 ; i >= 0 ; i--){
                    if(x & (1<<i)) bit[++t] = 1 ;
                    else   bit[++t] = 0 ;
               }
          }
          else  t -= 2 ;
          s++ ;
     }
     for(i = 1 ; i < t ; i += 8){
         x = 0 ;
         for(j = 0 ; j <= 7 ; j++){
              if(bit[i+j]) x |= (1<<(7-j)) ;
         }
         lis[lisszie++] = x ;
     }
     return lisszie ;
}

char word[3008] ;
char text[3008] ;

int  main(){
     int n , m  , i  ;
     while(cin>>n){
          ac.init() ;
          for(i = 1 ; i <= n ; i++){
              scanf("%s" ,  word) ;
              ac.insert(encode(word) , i) ;
          }
          ac.makeAC() ;
          cin>>m ;
          while(m--){
              scanf("%s" , text) ;
              printf("%d\n" , ac.ask(encode(text) , n)) ;
          }
          puts("") ;
     }
     return 0 ;
}


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