Cod sursa(job #3357790)

Utilizator TestLicenta123Test Test TestLicenta123 Data 13 iunie 2026 14:55:02
Problema Aho-Corasick Scor 25
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.51 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>

std::vector<int> ans(100, 0);

struct Trie {
private:
    struct Vertex {
        int next[26] = {0};
        int fail = -1;
        int output = -1;

        Vertex() {
            for (int &i : next) i = -1;
        }
    };

    std::vector<Vertex> cont;

    int &next(int node, char c) {
        return cont[node].next[c - 'a'];
    }

    int &output(int node) {
        return cont[node].output;
    }

    int &fail(int node) {
        return cont[node].fail;
    }

    void push_links() {
        std::queue<int> q;
        for (int i = 0; i < 26; ++i) {
            if (next(0, 'a' + i) != -1) {
                int child = next(0, 'a' + i);
                fail(child) = 0;
                q.push(child);
            } else {
                next(0, 'a' + i) = 0;
            }
        }

        while (!q.empty()) {
            int u = q.front();
            q.pop();

            for (int i = 0; i < 26; ++i) {
                char c = 'a' + i;
                int &v = next(u, c);
                if (v != -1) {
                    fail(v) = next(fail(u), c);
                    output(v) = (output(fail(v)) != -1) ? output(fail(v)) : output(v);
                    q.push(v);
                } else {
                    next(u, c) = next(fail(u), c);
                }
            }
        }
    }

public:
    Trie() {
        cont.emplace_back();
    }

    void add_word(const std::string &str, int idx) {
        int node = 0;
        for (char c : str) {
            if (next(node, c) == -1) {
                next(node, c) = cont.size();
                cont.emplace_back();
            }
            node = next(node, c);
        }
        output(node) = idx;
    }

    void compute() {
        fail(0) = 0;
        push_links();
    }

    void advance(int &state, char c) {
        state = next(state, c);
        int temp = state;
        while (temp != 0 && output(temp) != -1) {
            ans[output(temp)]++;
            temp = fail(temp);
        }
    }
};

int main() {
    std::ifstream input("ahocorasick.in");
    std::ofstream output("ahocorasick.out");
    Trie trie;
    std::string s;
    int n;
    input >> s >> n;
    std::vector<std::string> words(n);
    for (int i = 0; i < n; ++i) {
        input >> words[i];
        trie.add_word(words[i], i);
    }
    trie.compute();
    int state = 0;
    for (char c : s) {
        trie.advance(state, c);
    }

    for (int i = 0; i < n; ++i) {
        output << ans[i] << '\n';
    }
    return 0;
}