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'\npath:\n", 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, "\n" ); 36 return; 37 } 38 } 39 } 40 void build() { 41 fprintf( stderr, "\n\nbuild\n" ); 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\n", v, fail[v], v, last[v] ); 60 qu.push(v); 61 } 62 } 63 fprintf( stderr, "\n" ); 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\n", ac.ans[i] ); 100 }