Cod sursa(job #3332341)

Utilizator coco11coraline kalbfleisch coco11 Data 6 ianuarie 2026 11:21:01
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.58 kb
#include <bits/stdc++.h>
using namespace std;

struct Node {
    array<int, 26> next;   // transitions
    int fail;              // failure link
    vector<int> out;       // indices of words ending here
    Node() {
        next.fill(-1);
        fail = 0;
    }
};

class AhoCorasick {
    vector<Node> trie;
public:
    AhoCorasick() { trie.emplace_back(); }

    void insert(const string &word, int index) {
        int node = 0;
        for (char ch : word) {
            int c = ch - 'a';
            if (trie[node].next[c] == -1) {
                trie[node].next[c] = trie.size();
                trie.emplace_back();
            }
            node = trie[node].next[c];
        }
        trie[node].out.push_back(index);
    }

    void build() {
        queue<int> q;
        // initialize root transitions
        for (int c = 0; c < 26; c++) {
            int nxt = trie[0].next[c];
            if (nxt != -1) {
                trie[nxt].fail = 0;
                q.push(nxt);
            } else {
                trie[0].next[c] = 0;
            }
        }
        // BFS
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int c = 0; c < 26; c++) {
                int v = trie[u].next[c];
                if (v != -1) {
                    trie[v].fail = trie[trie[u].fail].next[c];
                    // merge outputs
                    trie[v].out.insert(trie[v].out.end(),
                                       trie[trie[v].fail].out.begin(),
                                       trie[trie[v].fail].out.end());
                    q.push(v);
                } else {
                    trie[u].next[c] = trie[trie[u].fail].next[c];
                }
            }
        }
    }

    vector<int> search(const string &text, int nWords) {
        vector<int> result(nWords, 0);
        int node = 0;
        for (char ch : text) {
            int c = ch - 'a';
            node = trie[node].next[c];
            for (int idx : trie[node].out) {
                result[idx]++;
            }
        }
        return result;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("ahocorasick.in", "r", stdin);
    freopen("ahocorasick.out", "w", stdout);

    string A;
    int n;
    cin >> A >> n;
    vector<string> words(n);
    for (int i = 0; i < n; i++) cin >> words[i];

    AhoCorasick ac;
    for (int i = 0; i < n; i++) ac.insert(words[i], i);
    ac.build();

    vector<int> ans = ac.search(A, n);
    for (int x : ans) cout << x << "\n";
}