Cod sursa(job #1553551)

Utilizator ZenusTudor Costin Razvan Zenus Data 20 decembrie 2015 00:34:48
Problema Aho-Corasick Scor 45
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <bits/stdc++.h>

using namespace std;

const int nmax = 1000000 + 10;

struct trie
{
    trie *nxt[26];
    trie *phi;
    int nr;

    trie()
    {
        for (int i = 0 ; i < 26 ; ++i)
        nxt[i] = 0;
        phi = 0;
        nr = 0;
    }
};

trie *root , *aux , *crt;
trie *iq[nmax] , *w[nmax];
string s , t;
int n , i , p , u;

void add(trie *node , int p)
{
    int c = t[p] - 'a';

    if (p == t.size())
    {
        w[i] = node;
        return ;
    }

    if (node -> nxt[c]) ;
    else node -> nxt[c] = new trie();

    add(node -> nxt[c] , p + 1);
}

void mark(trie *node , int p)
{
    if (p == s.size()) return;
    int c = s[p] - 'a';

    while (node - root && !node -> nxt[c])
    node = node -> phi;

    if (node -> nxt[c]) node = node -> nxt[c];

    node -> nr += 1;
    mark(node , p + 1);
}

void solve(trie *node)
{
    for (int i = 0 ; i < 26 ; ++i)
    if (node -> nxt[i])
    solve(node -> nxt[i]);

    node -> phi -> nr += node -> nr;
}

int main()
{
freopen("ahocorasick.in" , "r" , stdin);
freopen("ahocorasick.out" , "w" , stdout);

root = new trie();
root -> phi = root;

cin >> s;
cin >> n;

for (i = 1 ; i <= n ; ++i)
{
    cin >> t;
    add(root , 0);
}

p = u = 1;
iq[1] = root;

while (p <= u)
{
    crt = iq[p];
    p += 1;

    for (i = 0 ; i < 26 ; ++i)
    if (crt -> nxt[i])
    {
        aux = crt -> phi;

        while (aux - root)
        {
            if (aux -> nxt[i]) break;
            aux = aux -> phi;
        }

        if (aux -> nxt[i] && aux -> nxt[i] - crt -> nxt[i]) aux = aux -> nxt[i];
        crt -> nxt[i] -> phi = aux;

        u += 1;
        iq[u] = crt -> nxt[i];
    }
}

mark(root , 0);
solve(root);

for (i = 1 ; i <= n ; ++i)
cout << w[i] -> nr << '\n';

return 0;
}