Cod sursa(job #1812090)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 21 noiembrie 2016 20:30:15
Problema Aho-Corasick Scor 25
Compilator cpp Status done
Runda Arhiva educationala Marime 2.61 kb
#include <fstream>
#include <vector>
#include <deque>

std::ifstream in ( "ahocorasick.in"  );
std::ofstream out( "ahocorasick.out" );

const int DIM = 105;
const int EXP = 10005;
const int LEN = 1000005;

struct T {
    int cntw, cntc, cnto;
    std::vector<T*> fte;
    T *chl[26], *bke;
    T() {
        this -> cntw = this -> cntc = this -> cnto = 0; this -> bke = NULL;
        for( int i = 0; i < 26; i ++ ) { this -> chl[i] = NULL; } }
} *r = new T;

T* insert( T *n, char *str ) {
    if( *str == 0 ) {
        return n; }
    else {
        if( n -> chl[*str - 'a'] == NULL ) {
            n -> chl[*str - 'a'] = new T; n -> cntc ++; }
        n -> chl[*str - 'a'] = insert( n -> chl[*str - 'a'], str + 1 ); }
    return n; }

T* clear( T *n ) {
    n -> cnto = 0; n -> bke = NULL;
    n -> fte.clear();
    for( int i = 0; i < 26; i ++ ) {
        if( n -> chl[i] != NULL ) {
            n -> chl[i] = clear( n -> chl[i] ); } }
    return n; }

T* build( T *r ) {
    std::deque<T*> que; que.push_back( r );
    while( que.empty() == false ) {
        T *n = que.front(); que.pop_front();
        for( int i = 0; i < 26; i ++ ) {
            if( n -> chl[i] == NULL ) {
                continue; }
            T *aux = n -> bke;
            while( aux != NULL && aux -> chl[i] == NULL ) {
                aux = aux -> bke; }
            if( aux == NULL ) {
                n -> chl[i] -> bke = r; }
            else {
                n -> chl[i] -> bke = aux -> chl[i]; }
            n -> chl[i] -> bke -> fte.push_back( n -> chl[i] );
            que.push_back( n -> chl[i] ); } }
    return r; }

T* count( T *n, char *str ) {
    if( *str == 0 ) {
        return n; }
    T *aux = n;
    while( aux != r && aux -> chl[*str - 'a'] == NULL ) {
        aux = aux -> bke; }
    if( aux -> chl[*str - 'a'] != NULL ) {
        aux = aux -> chl[*str - 'a']; }
    aux -> cnto ++; aux = count( aux, str + 1 );
    return n; }

T* psum( T *n ) {
    for( auto nxt : n -> fte ) {
        nxt = psum( nxt ); n -> cnto += nxt -> cnto; }
    return n; }

int cntocc( T *n, char *str ) {
    if( *str == 0 ) {
        return n -> cnto; }
    if( n -> chl[*str - 'a'] == 0 ) {
        return 0; }
    return cntocc( n -> chl[*str - 'a'], str + 1 ); }

char wrd[DIM][EXP], str[LEN];

int main( int argc, const char *argv[] ) {
    std::ios::sync_with_stdio( false );
    int n; in >> str >> n;
    for( int i = 1; i <= n; i ++ ) {
        in >> wrd[i];
        r = insert( r, wrd[i] ); }
    r = clear( r ); r = build( r );
    r = count( r, str ); r = psum( r );
    for( int i = 1; i <= n; i ++ ) {
        out << cntocc( r, wrd[i] ) << std::endl; }
    
    return 0; }