Cod sursa(job #2374035)

Utilizator akaprosAna Kapros akapros Data 7 martie 2019 16:38:15
Problema Aho-Corasick Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#include <bits/stdc++.h>
#define maxN 1000002
#define SIGMA 26

using namespace std;

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

char a[maxN], s[maxN / 10 + 2];

struct Trie
{
    Trie* sons[SIGMA];
    Trie* failLink, *outLink;
    vector < int > WordId;
    int cnt;
} nodes[maxN / 2];
Trie* T;
queue < Trie* > Q;
vector < Trie* > outQ;
int nodesCount = 0;

int frq[maxN / 10 + 2];

Trie* newTrie()
{
    return &nodes[nodesCount++];
}

void Insert(Trie* node, char *w, int id)
{
    if (*w == NULL)
    {
        node->WordId.push_back(id);
        return ;
    }
    if (node->sons[*w - 'a'] == NULL)
        node->sons[*w - 'a'] = newTrie();
    Insert(node->sons[*w - 'a'], w + 1, id);
}
void goTo()
{
    T->failLink = T->outLink = NULL;
    for (int c = 0; c < SIGMA; ++ c)
        if (T->sons[c] != NULL)
        {
            Q.push(T->sons[c]);
            T->sons[c]->failLink = T;
        }
}
void compFailLink()
{
    outQ.push_back(T);
    while (!Q.empty())
    {
        Trie* node = Q.front();
        outQ.push_back(node);
        Q.pop();
        for (int c = 0; c < SIGMA; ++ c)
            if (node->sons[c] != NULL)
            {
                Trie *fL = node->failLink;
                while (fL != T && fL->sons[c] == NULL)
                    fL = fL->failLink;
                if (fL->sons[c] != NULL)
                    node->sons[c]->failLink = fL->sons[c];
                else
                    node->sons[c]->failLink = T;
                Q.push(node->sons[c]);
            }
    }
}
void getSol()
{
    int m = strlen(a);
    Trie* node = T;
    for (int i = 0; i < m; ++ i)
    {
        while (node != T && node->sons[a[i] - 'a'] == NULL)
            node = node->failLink;
        if (node->sons[a[i] - 'a'] != NULL)
            node = node->sons[a[i] - 'a'];
        ++ node->cnt;
    }

    while (!outQ.empty())
    {
        node = outQ.back();
        outQ.pop_back();
        if (node->failLink != NULL)
            node->failLink->cnt += node->cnt;
        for (int id : node->WordId)
            frq[id] += node->cnt;
    }
}

int main()
{
    int n;
    scanf("%s", a);
    scanf("%d\n", &n);
    T = newTrie(); ///root
    for (int i = 0; i < n; ++ i)
    {
        scanf("%s\n", &s);
        Insert(T, s, i);
    }
    goTo();
    compFailLink();
    getSol();

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

    return 0;
}