Cod sursa(job #2417057)

Utilizator akaprosAna Kapros akapros Data 28 aprilie 2019 19:48:45
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>
#define maxL 10002
#define maxN 1000002
#define maxW 102
#define SIGMA 26

using namespace std;


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

int n;
char s[maxN], a[maxL];

struct Trie
{
    int cnt;
    Trie *fLink, *sons[SIGMA];
    vector < short int > idx;
} *Root;

vector < Trie* > outQ;

int frq[maxW];


Trie* new_emptyNode()
{
    Trie *node = new Trie();
    node->fLink = NULL;
    for (int c = 0; c < SIGMA; ++ c)
        node->sons[c] = NULL;
    node->cnt = 0;
    return node;
}
inline void insert(Trie *node, char *w, short int id)
{
    if (*w == NULL)
    {
        node->idx.push_back(id);
        //node->outLink = node;
        return ;
    }
    if (node->sons[*w - 'a'] == NULL)
        node->sons[*w - 'a'] = new_emptyNode();
    insert(node->sons[*w - 'a'], w + 1, id);
}
void compFail()
{
    Root->fLink = Root;
    outQ.push_back(Root);

    for (int ch = 0; ch < SIGMA; ++ ch)
        if (Root->sons[ch] != NULL)
        {
            Root->sons[ch]->fLink = Root;
            outQ.push_back(Root->sons[ch]);
        }
    int sz = outQ.size(), p = 1;
    while (p < sz)
    {
        Trie *node = outQ[p ++];

        for (int ch = 0; ch < SIGMA; ++ ch)
            if (node->sons[ch] != NULL)
            {
                Trie *nxt = node->fLink;

                while (nxt->sons[ch] == NULL && nxt != Root)
                    nxt = nxt->fLink;
                if (nxt->sons[ch] != NULL)
                    node->sons[ch]->fLink = nxt->sons[ch];
                else node->sons[ch]->fLink = Root;
                outQ.push_back(node->sons[ch]);
                ++ sz;
            }
    }
}
void StrOcc()
{
    Trie* node = Root;
    int len = strlen(s);
    for (int i = 0; i < len; ++ i)
    {
        while (node->sons[s[i] - 'a'] == NULL && node != Root)
            node = node->fLink;
        if (node->sons[s[i] - 'a'] != NULL)
        {
            node = node->sons[s[i] - 'a'];
            node->cnt ++;
        }
    }
}
void compFrq()
{
    while (!outQ.empty())
    {
        Trie *node = outQ.back();
        outQ.pop_back();
        if (!node->cnt) continue;
        for (int id : node->idx)
            frq[id] += node->cnt;
        node->fLink->cnt += node->cnt;
    }
}
int main()
{
    Root = new_emptyNode();
    scanf("%s\n%d\n", s, &n);

    for (int i = 0; i < n; ++ i)
    {
        scanf("%s\n", a);
        insert(Root, a, i);
    }
    compFail();
    StrOcc();
    compFrq();
    for (int i = 0; i < n; ++ i) printf("%d\n", frq[i]);
    return 0;
}