Cod sursa(job #3303395)

Utilizator Cristian_NegoitaCristian Negoita Cristian_Negoita Data 15 iulie 2025 13:30:58
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.79 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int SIGMA = 26, NMAX = 2e5;
int n, ans[NMAX];

struct AhoCorasick
{
    struct TrieNode
    {
        TrieNode *children[SIGMA], *fail_link;
        int visited = 0;
        vector<int> ending_words;
        TrieNode() { fill(children, children + SIGMA, nullptr); }
    };
    TrieNode *root = new TrieNode;
    vector<TrieNode*> BFS_order;

    void insert_word(const string &word, int idx)
    {
        TrieNode *node = root;
        for(char ch : word)
        {
            if(node->children[ch - 'a'] == nullptr)
                node->children[ch - 'a'] = new TrieNode;
            node = node->children[ch - 'a'];
        }
        node->ending_words.push_back(idx);
    }

    void build_automaton()
    {
        queue<TrieNode*> q;
        root->fail_link = root;
        q.push(root);
        while(!q.empty())
        {
            TrieNode *node = q.front();
            q.pop();
            BFS_order.push_back(node);
            for(char ch = 'a'; ch <= 'z'; ch++)
            {
                TrieNode *child = node->children[ch - 'a'];
                if(child == nullptr)
                    continue;
                TrieNode *fall_back = node->fail_link;
                while(fall_back != root && fall_back->children[ch - 'a'] == nullptr)
                    fall_back = fall_back->fail_link;
                if(fall_back->children[ch - 'a'] != nullptr && fall_back->children[ch - 'a'] != child)
                    child->fail_link = fall_back->children[ch - 'a'];
                else
                    child->fail_link = root;
                q.push(child);
            }
        }
    }

    void search_text(const string &text)
    {
        TrieNode *node = root;
        for(char ch : text)
        {
            while(node != root && node->children[ch - 'a'] == nullptr)
                node = node->fail_link;
            if(node->children[ch - 'a'] != nullptr)
                node = node->children[ch - 'a'];
            node->visited++;
        }
        reverse(BFS_order.begin(), BFS_order.end());
        for(TrieNode *node : BFS_order)
        {
            for(int idx : node->ending_words)
                ans[idx] += node->visited;
            node->fail_link->visited += node->visited;
        }
    }
};
AhoCorasick aho_corasick;

int main()
{
    string text;
    fin >> text >> n;
    for(int i = 0; i < n; i++)
    {
        string word;
        fin >> word;
        aho_corasick.insert_word(word, i);
    }
    aho_corasick.build_automaton();
    aho_corasick.search_text(text);
    for(int i = 0; i < n; i++)
        fout << ans[i] << "\n";

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