Pagini recente » Cod sursa (job #545540) | Cod sursa (job #678056) | Cod sursa (job #1853791) | Cod sursa (job #2516076) | Cod sursa (job #98564)
Cod sursa(job #98564)
// chestii grele
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <queue>
#define RUN_IT
using namespace std;
int N, M, L, ret;
char A[10111111], cuv[50111][22];
clock_t start, end;
void clock_it( string x )
{
#ifndef RUN_IT
clock_t at = clock();
cout << x << " = " << 1.0 * ( at - start ) / CLOCKS_PER_SEC << endl;
#endif
}
#define V 3
int ID_POOL;
struct node
{
int id;
char term;
node * to[ V ];
node()
{
for( int i = 0; i < V; ++i )
to[i] = NULL;
id = -1;
term = 0;
}
} * R;
void t_init()
{
R = new node();
R->id = 0;
ID_POOL = 1;
}
void t_add_word( char * s )
{
node * at = R;
for( int i = 0; i < M; ++i )
{
if( at->to[ s[i] ] )
at = at->to[ s[i] ];
else
{
node * n = new node();
n->id = ID_POOL++;
at->to[ s[i] ] = n;
at = n;
}
}
at->term = 1;
}
void print_trie( node * n, int pos)
{
int nr(0);
for( int x = 0; x < V; ++x )
if( n->to[x] )
{
if( nr )
cout << string( pos, ' ' );
cout << (int)(x);
print_trie( n->to[x], pos + 1 );
++nr;
}
if( !nr )
cout << endl;
}
#define MAX_SZ 666555
int f[MAX_SZ], out[MAX_SZ];
int g[MAX_SZ][V];
queue<int> Q;
int nr_word, nr_state;
void df( node * n )
{
for( int x = 0; x < V; x++ )
{
if( n->to[x] )
{
g[ n->id ][ x ] = n->to[x]->id;
df( n->to[x] );
}
else
{
if( n->id == 0 ) // root
g[ 0 ][ x ] = 0;
else
g[ n->id ][ x ] = -1;
}
}
out[ n->id ] = n->term;
}
void build_automata()
{
nr_state = ID_POOL;
clock_it( "Resizing" );
df( R );
clock_it( "df" );
for( int x = 0; x < V; ++x )
if( R->to[x] )
f[ R->to[x]->id ] = 0,
Q.push( R->to[x]->id );
clock_it( "graph" );
while( (int)Q.size() )
{
int r = Q.front(), u, v; Q.pop();
for( int x = 0; x < V; ++x )
if( (u=g[ r ][ x ]) != -1 ) // u is the son of r with edge x
{
Q.push( u );
v = f[ r ];
while( g[ v ][ x ] == -1 )
v = f[ v ];
f[ u ] = g[ v ][ x ];
out[ u ] |= out[ f[u] ];
}
}
clock_it( "queue" );
}
inline int process_character( int & q, char x )
{
while( g[ q ][ x ] == -1 )
q = f[ q ];
q = g[ q ][ x ];
return out[ q ];
}
int process_string()
{
int q = 0, nr_found = 0, op;
for( int i = 0; i < L; ++i )
{
while( g[ q ][ A[i] ] == -1 )
q = f[ q ];
q = g[ q ][ A[i] ];
// cout << "pos : " << i << " found " << v << endl;
nr_found += out[q];
}
return nr_found;
}
void gen()
{
freopen("abc2.in", "w", stdout);
L = 10000000, N = 50000, M = 20;
for( int i = 0; i < L; i++ )
printf("%c", (char)( 'a' + rand() % 3 ) ); printf("\n");
for( int c = 0; c < N; c++ )
{
for( int i = 0; i < M; i++ )
printf("%c", (char)( 'a' + rand() % 3 ) ); printf("\n");
}
}
int main()
{
// gen();
freopen("abc2.in", "r", stdin);
freopen("abc2.out", "w", stdout);
start = clock();
int i, j, l, k;
gets( A );
L = strlen( A );
N = 0;
while( gets( cuv[++N] ) );
--N;
if( N == 0 )
{
printf("0\n");
return 0;
}
M = strlen(cuv[1]);
if( M > L )
{
printf("0\n");
return 0;
}
for( l = 0; l < L; l++ )
A[l] -= 'a';
for( i = 1; i <= N; i++ )
for( l = 0; l < M; l++ )
cuv[i][l] -= 'a';
clock_it( "reading" );
t_init();
for( int i = 1; i <= N; i++ )
t_add_word( cuv[i] );
// print_trie( R, 0 );
build_automata();
// cout << MyAC.process_string() << endl;
int q = 0;
clock_it( "starting string processing" );
for( i = 0; i < L; ++i )
{
while( g[ q ][ A[i] ] == -1 )
q = f[ q ];
q = g[ q ][ A[i] ];
ret += out[q];
}
cout << ret << endl;
clock_it( "total" );
return 0;
}