Cod sursa(job #1969152)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 18 aprilie 2017 12:10:39
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include <bits/stdc++.h>

using namespace std;

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

const int sigma = 26;

const int nmax = 1e2 + 10;
const int lmax = 1e4 + 10;

const int qmax = nmax * lmax;

struct trie {
    int cnt;
    trie *phi, *son[sigma];

    trie() {
        cnt = 0;

        phi = NULL;
        for (int i = 0; i < sigma; ++i)
            son[i] = NULL;
    }
};

int n;
string str, s;
trie *root, *link[nmax];

int dim;
trie *q[qmax];

void _add(trie *, int, int);

void input() {
    fin >> str;

    fin >> n; root = new trie;
    for (int i = 1; i <= n; ++i) {
        fin >> s;
        _add(root, 0, i);
    }
}

void _add(trie *node, int pos, int idx) {
    if (pos == s.size()) {
        link[idx] = node;
        return;
    }

    int to = s[pos] - 'a';
    if (node -> son[to] == NULL)
        node -> son[to] = new trie;

    _add(node -> son[to], pos + 1, idx);
}

void compute_phi() {
    root -> phi = root;

    q[++dim] = root;
    for (int i = 1; i <= dim; ++i) {
        trie *node = q[i];

        for (int to = 0; to < sigma; ++to) {
            if (node -> son[to] == NULL)
                continue;

            trie *k = node -> phi;
            while (k != root && k -> son[to] == NULL)
                k = k -> phi;
            if (k -> son[to] != NULL && k != node)
                k = k -> son[to];

            node -> son[to] -> phi = k;
            q[++dim] = node -> son[to];
        }
    }
}

void compute_answer() {
    trie *k = root;
    for (int i = 0; str[i]; ++i) {
        int to = str[i] - 'a';
        while (k != root && k -> son[to] == NULL)
             k = k -> phi;
        if (k -> son[to] != NULL)
            k = k -> son[to];

        k -> cnt++;
    }

    for (int i = dim; i; --i)
        q[i] -> phi -> cnt += q[i] -> cnt;
}

void output() {
    for (int i = 1; i <= n; ++i)
        fout << link[i] -> cnt << '\n';
}

int main() {
    input();
    compute_phi();
    compute_answer();
    output();

    return 0;
}