zoukankan      html  css  js  c++  java
  • bzoj 3172

    收获:AC自动机定数组大小时,如果不确定,就定10^6(极限了)

      1 /**************************************************************
      2     Problem: 3172
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:688 ms
      7     Memory:321164 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <queue>
     13 #include <vector>
     14 #define maxn 1000010
     15 #define fprintf(...)
     16 using namespace std;
     17  
     18 struct AC {
     19     int son[maxn][27], ntot;
     20     int fail[maxn], last[maxn];
     21     vector<int> vc[maxn];
     22     int ans[300];
     23  
     24     void insert( int id, const char *P ) {
     25         int u=0;
     26         fprintf( stderr, "insert '%s'
    path:
    ", P );
     27         while(1) {
     28             fprintf( stderr, "%d ", u );
     29             if( *P ) {
     30                 int c=(*P++)-'a';
     31                 if( !son[u][c] ) son[u][c]=++ntot;
     32                 u=son[u][c];
     33             } else {
     34                 vc[u].push_back(id);
     35                 fprintf( stderr, "
    " );
     36                 return;
     37             }
     38         }
     39     }
     40     void build() {
     41         fprintf( stderr, "
    
    build
    " );
     42         queue<int> qu;
     43         for( int c=0; c<27; c++ ) {
     44             int v=son[0][c];
     45             if( !v ) continue;
     46             qu.push( v );
     47             fail[v] = last[v] = 0;
     48         }
     49         while( !qu.empty() ) {
     50             int u=qu.front();
     51             qu.pop();
     52             for( int c=0; c<27; c++ ) {
     53                 int v=son[u][c];
     54                 int w=fail[u];
     55                 if( !v ) continue;
     56                 while( w && !son[w][c] ) w=fail[w];
     57                 fail[v] = son[w][c];
     58                 last[v] = vc[son[w][c]].size() ? son[w][c] : last[son[w][c]];
     59                 fprintf( stderr, "fail[%d]=%d  last[%d]=%d
    ", v, fail[v], v, last[v] );
     60                 qu.push(v);
     61             }
     62         }
     63         fprintf( stderr, "
    " );
     64     }
     65     void add( int u ) {
     66         if( !u ) return;
     67         add(last[u]);
     68         for( int t=0; t<vc[u].size(); t++ )
     69             ans[vc[u][t]]++;
     70     }
     71     void search( const char *T ) {
     72         int n=strlen(T);
     73         int u=0;
     74         for( int i=0; i<n; i++ ) {
     75             int c=T[i]-'a';
     76             while( u && !son[u][c] ) u=fail[u];
     77             u=son[u][c];
     78             if( vc[u].size() ) add(u);
     79             else if( last[u] ) add(last[u]);
     80         }
     81     }
     82 }ac;
     83  
     84 int n;
     85 char str[200010001];
     86  
     87 int main() {
     88     scanf( "%d", &n );
     89     int len=0;
     90     for( int i=1; i<=n; i++ ) {
     91         scanf( "%s", str+len );
     92         ac.insert( i, str+len );
     93         len += strlen(str+len);
     94         str[len++] = 'z'+1;
     95     }
     96     ac.build();
     97     ac.search( str );
     98     for( int i=1; i<=n; i++ )
     99         printf( "%d
    ", ac.ans[i] );
    100 }
    View Code
  • 相关阅读:
    重构与模式:改善代码三部曲中的第三部
    将博客搬至CSDN
    管理之道(二十二)
    管理之道(二十一)
    管理之道(二十)
    管理之道(十九)
    管理之道(十八)
    管理之道(十七)
    管理之道(十六)
    管理之道(十五)
  • 原文地址:https://www.cnblogs.com/idy002/p/4333347.html
Copyright © 2011-2022 走看看