Cod sursa(job #98564)

Utilizator ZeusCatalin Tiseanu Zeus Data 10 noiembrie 2007 14:30:06
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Happy Coding 2007 Marime 5.87 kb

// 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;    
}