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
原文地址:https://www.cnblogs.com/idy002/p/4333347.html