Cod sursa(job #1439726)

Utilizator UPB_Radu_Stefan_SilviuDont Blink UPB_Radu_Stefan_Silviu Data 23 mai 2015 00:17:38
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.59 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
#define LMax 1000010
#define NMax 1000010

using namespace std;

const char IN[] = "censor.in", OUT[] = "censor.out";

struct node {

    int fail, parent, level, match;
    int next[26];

    node () {

        for ( int i = 0; i < 26; ++ i ) {
            next[i] = 0;
        }

        level = 0;
        parent = 0;
        fail = 0;
        match = 0;
    }

    bool operator < ( node const & other ) const {
        return level < other.level;
    }
};

int N, next[NMax], prev[NMax];
char s[LMax], t[LMax];

vector<node> v;
vector<int> Index;

int find( int x, int * P ) {
    if ( P[x] == x )
        return x;
    P[x] = find(P[x], P);
    return P[x];
}

void add( int n , char * s ) {

    if ( *s == 0 ) {
        v[n].match = 1;
        return;
    }

    if ( v[n].next[ *s - 'a' ] == 0 ) {
        node no;
        no.parent = n;
        no.level = v[n].level + 1;
        v.push_back(no);
        v[n].next[ *s - 'a' ] = v.size() - 1;

    }

    add( v[n].next[ *s - 'a' ], s + 1 );

}

void bfs() {

    for ( int i = 0; i < 26; ++ i ) if ( v[0].next[i] )
        Index.push_back(v[0].next[i]);

    for ( int i = 0; i < Index.size(); ++ i ) {

        for ( int j = 0; j < 26; ++ j ) if( v[Index[i]].next[j] )
            Index.push_back(v[Index[i]].next[j]);

        for ( int j = 0; j < 26; ++ j ) if( v[Index[i]].next[j] ){
            v[ v[Index[i]].next[j] ].fail = v[ v[Index[i]].fail ].next[j];
        }

        for ( int j = 0; j < 26; ++ j ) if ( ! v[Index[i]].next[j] ) {
            v[Index[i]].next[j] = v[ v[Index[i]].fail ].next[j];
        }

    }

}

void get( char * s ) {

    static int Prefix[NMax];

    int N = strlen(s + 1);
    int k = 0;

    for ( int i = 1; i <= N + 5; ++ i ) {
        next[i] = prev[i] = i;
    }

    for ( int i = 1; i <= N; i = find(i + 1, next) ) {
        k = v[k].next[s[i] - 'a'];

        if ( v[k].match ) {
            for ( int j = 1; j <= v[k].level; ++ j, i = find(i - 1, prev) ) {
                next[i] = find(i + 1, next);
                prev[i] = find(i - 1, prev);
            }
            k = Prefix[i];
        }
        Prefix[i] = k;
    }

    int j = 0;
    for ( int i = find(1, next); i <= N; i = find(i + 1, next) )
        s[ ++ j ] = s[i];
    s[ ++ j ] = 0;

}

int main() {

    freopen(IN, "r", stdin);
    freopen(OUT, "w", stdout);

    scanf("%s%d", s + 1, &N);

    node no;
    v.push_back(no);

    for ( int i = 1; i <= N; ++ i ) {
        scanf("%s", t + 1);
        add(0, t + 1);
    }

    bfs();
    get(s);

    printf("%s\n", s + 1);

    return 0;
}