Cod sursa(job #2414653)

Utilizator akaprosAna Kapros akapros Data 24 aprilie 2019 21:00:57
Problema Aho-Corasick Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.89 kb
#include <bits/stdc++.h>
#define maxN 1000005
#define maxL 10005
#define SIGMA 26
#define maxW 102
using namespace std;

FILE *fin = freopen("ahocorasick.in", "r", stdin);
FILE *fout = freopen("ahocorasick.out", "w", stdout);

/* ====================== */
int n;
char Word[maxL];
char Txt[maxN];
/* ====================== */
struct Trie
{
    Trie *son[26];
    vector < int > idx;
    int cnt;
    Trie *f;
};
Trie* T;
queue < Trie* > q;
vector < Trie* > OutQ;
int frq[maxW];
/* ====================== */


Trie* new_empty_node()
{
    Trie *node = new Trie;
    node->f = NULL;
    node->idx.clear();
    node->cnt = 0;
    for(int i = 0; i < SIGMA; ++ i)
        node->son[i] = NULL;
    return node;
}

void insert(Trie* node, char *w, int idx)
{
    if (*w == 0)
    {
        node->idx.push_back(idx);
        return;
    }
    if (node->son[*w - 'a'] == NULL)
        node->son[*w - 'a'] = new_empty_node();

    insert(node->son[*w - 'a'], w + 1, idx);
}

void Goto()
{
    T->f = T;
    //T->out = T;

    for (int i = 0; i < SIGMA; ++ i)
        if (T->son[i] == NULL)
        {
            T->son[i] = new_empty_node();
            T->son[i]->f = T;
            //T->son[i]->out = T;
        }
        else
        {
            T->son[i]->f = T;
            //T->son[i]->out = T;
            q.push(T->son[i]);
        }
}

void Fail()
{
    OutQ.push_back(T);
    while (!q.empty())
    {
        Trie* st = q.front();
        q.pop();
        OutQ.push_back(st);

        for (int i = 0; i < SIGMA; ++ i)
            if (st->son[i] != NULL)
            {
                Trie* failure = st->f;
                while (failure != T && failure->son[i] == NULL)
                    failure = failure->f;

                failure = failure->son[i];
                st->son[i]->f = failure;
                /*if (failure->idx)
                    st->son[i]->out = failure;
                else
                    st->son[i]->out = failure->out;*/
                q.push(st->son[i]);
            }
    }
}

Trie* NextSt(Trie* node, int ch)
{
    Trie* ret = node;

    while (ret->son[ch] == NULL)
        ret = ret->f;

    return ret->son[ch];
}

void Out()
{
    int len = strlen(Txt);

    Trie* st = T;
    for (int i = 0; i < len; ++ i)
    {
        st = NextSt(st, Txt[i] - 'a');
        ++ st->cnt;
    }

    while (!OutQ.empty())
    {
        Trie* st = OutQ.back();
        OutQ.pop_back();

        for (int w : st->idx)
            frq[w] += st->cnt;
        st->f->cnt += st->cnt;
    }
}

int main()
{
    gets(Txt);
    scanf("%d\n", &n);
    T = new_empty_node();
    for (int i = 1; i <= n; ++ i)
    {
        gets(Word);
        insert(T, Word, i);
    }

    Goto();
    Fail();
    Out();

    for (int i = 1; i <= n; ++ i)
        printf("%d\n", frq[i]);
    return 0;
}