Cod sursa(job #1508995)

Utilizator retrogradLucian Bicsi retrograd Data 23 octombrie 2015 13:21:43
Problema Aho-Corasick Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <fstream>
#include <iostream>
#include <cassert>
#include <vector>

using namespace std;

int Vec[1000005], Next[1000005];

struct Node {
    int cnt, leg[27], bad, adj;
} T[1000005];
int root = 1, nodes = 1;

int Where[105];
char Tx[1000005], P[10005];

void addEdge(int a, int b) {
    ++nodes;
    Vec[nodes] = b;
    Next[nodes] = T[a].adj;
    T[a].adj = nodes;
}

int addWord(char str[]) {
    int node = root;
    for(int i=0; str[i]; i++) {
        int c = str[i] - 'a';

        if(T[node].leg[c] == 0) T[node].leg[c] = ++nodes;
        node = T[node].leg[c];
    }

    return node;
}

void build_bad(int node, int parent, int c) {
    if(node != root) {
        int bad = T[parent].bad;

        while(bad && T[bad].leg[c] == 0) bad = T[bad].bad;
        T[node].bad = (bad) ? T[bad].leg[c] : root;
        addEdge(T[node].bad, node);
    }

    for(c=0; c<='z'-'a'; c++)
        if(T[node].leg[c])
            build_bad(T[node].leg[c], node, c);
}

void solve(char str[]) {
    int node = root;

    for(int i=0; str[i]; i++) {
        int c = str[i] - 'a';

        while(node && T[node].leg[c] == 0) node = T[node].bad;
        node = (node) ? T[node].leg[c] : root;

        T[node].cnt += 1;
    }
}

void dfs(int node) {
    for(int i = T[node].adj; i; i = Next[i])
        dfs(Vec[i]), T[node].cnt += T[Vec[i]].cnt;
}


int main() {
    ifstream fin("ahocorasick.in");
    ofstream fout("ahocorasick.out");

    int n;

    fin>>Tx>>n;
    for(int i=1; i<=n; i++) {
        fin>>P;
        Where[i] = addWord(P);
    }

    build_bad(root, 0, 0);
    solve(Tx);
    dfs(root);

    for(int i=1; i<=n; i++) {
        fout<<T[Where[i]].cnt<<'\n';
    }
}