Cod sursa(job #1182493)

Utilizator darrenRares Buhai darren Data 6 mai 2014 17:18:52
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.37 kb
#include <fstream>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

int inow, val[1000002];

struct Trie
{
    int ind;
    Trie *next[26], *last;

    Trie()
    {
        ind = ++inow;
        for (int i = 0; i < 26; ++i)
            next[i] = 0;
        last = 0;
    }
};
Trie *R = new Trie();

int insert(Trie *T, char *now)
{
    if (*now == 0) return T->ind;

    if (T->next[*now - 'a'] == 0)
        T->next[*now - 'a'] = new Trie;

    return insert(T->next[*now - 'a'], now + 1);
}

char A[1000002], B[10002];
int where[102];
vector<Trie*> V[1000002];
queue<Trie*> Q;
int N;

bool S[1000002];
void Dfs(Trie *x)
{
    if (S[x->ind]) return;
    S[x->ind] = true;

    for (int i = 0; i < 26; ++i)
        if (x->next[i] != 0)
            Dfs(x->next[i]);
    for (vector<Trie*>::iterator it = V[x->ind].begin(); it != V[x->ind].end(); ++it)
    {
        Dfs(*it);
        val[x->ind] += val[(*it)->ind];
    }
}

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

    fin >> A;
    fin >> N;
    for (int i = 1; i <= N; ++i)
    {
        fin >> B;
        where[i] = insert(R, B);
    }

    Q.push(R);
    while (!Q.empty())
    {
        Trie *now = Q.front();
        Q.pop();

        for (int i = 0; i < 26; ++i)
            if (now->next[i] != 0)
            {
                Trie *tn = now->last;
                while (tn != 0 && tn->next[i] == 0)
                    tn = tn->last;

                if (tn == 0)
                    now->next[i]->last = R;
                else
                {
                    V[tn->next[i]->ind].push_back(now->next[i]);
                    now->next[i]->last = tn->next[i];
                }

                Q.push(now->next[i]);
            }
    }

    Trie *tnow = R;
    for (int i = 0; A[i] != 0; ++i)
    {
        if (tnow->next[A[i] - 'a'] != 0)
            tnow = tnow->next[A[i] - 'a'];
        else
        {
            while (tnow != 0 && tnow->next[A[i] - 'a'] == 0)
                tnow = tnow->last;
            if (tnow == 0) tnow = R;
            else           tnow = tnow->next[A[i] - 'a'];
        }
        ++val[tnow->ind];
    }

    Dfs(R);

    for (int i = 1; i <= N; ++i)
        fout << val[where[i]] << '\n';

    fin.close();
    fout.close();
}