Cod sursa(job #2635950)

Utilizator trifangrobertRobert Trifan trifangrobert Data 16 iulie 2020 02:01:33
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.33 kb
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

const int SIGMA = 26;
const int NMAX = 10005;

struct Node
{
    Node* link[SIGMA] = {};
    Node* suffixLink = nullptr;
    int cnt = 0;
};
vector <Node*> h[NMAX];

Node* AddSon(Node* aho, char ch)
{
    if (aho->link[ch - 'a'] == nullptr)
        aho->link[ch - 'a'] = new Node();
    return aho->link[ch - 'a'];
}

Node* AddString(Node* aho, string s)
{
    for (auto& ch : s)
        aho = AddSon(aho, ch);
    return aho;
}

void dfs_height(Node* aho, int height)
{
    h[height].push_back(aho);
    for (int i = 0; i < SIGMA; ++i)
        if (aho->link[i])
            dfs_height(aho->link[i], height + 1);
}

void son_suffix(Node* father)
{
    for (int i = 0; i < SIGMA; ++i)
    {
        if (father->link[i] == nullptr)
            continue;
        Node* son = father->link[i];
        son->suffixLink = father->suffixLink;
        while (son->suffixLink->link[i] == nullptr && son->suffixLink != son->suffixLink->suffixLink)
            son->suffixLink = son->suffixLink->suffixLink;
        if (son->suffixLink->link[i] != nullptr && son->suffixLink->link[i] != son)
            son->suffixLink = son->suffixLink->link[i];
    }
}

Node* Advance(Node* aho, char ch)
{
    while (aho->link[ch - 'a'] == nullptr && aho != aho->suffixLink)
        aho = aho->suffixLink;
    if (aho->link[ch - 'a'])
        aho = aho->link[ch - 'a'];
    return aho;
}

int main()
{
    ifstream fin("ahocorasick.in");
    ofstream fout("ahocorasick.out");
    string str;
    int N;
    fin >> str;
    fin >> N;
    Node* aho = new Node();
    aho->suffixLink = aho;
    vector <string> words(N);
    vector <Node*> wordNode(N);
    for (int i = 0; i < N; ++i)
    {
        fin >> words[i];
        wordNode[i] = AddString(aho, words[i]);
    }
    dfs_height(aho, 0);
    for (auto& i : h)
        for (auto& j : i)
            son_suffix(j);
    Node* node = aho;
    for (auto& x : str)
    {
        node = Advance(node, x);
        ++node->cnt;
    }
    reverse(begin(h), end(h));
    for (auto& i : h)
        for (auto& j : i)
            j->suffixLink->cnt += j->cnt;
    for (auto& i : wordNode)
        fout << i->cnt << "\n";
    fin.close();
    fout.close();
    return 0;
}