Cod sursa(job #3365629)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 22 septembrie 2026 21:01:29
Problema Aho-Corasick Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>

const int SIGMA = 26;
struct Node
{
    int to[SIGMA];
    int lsp;
    int jump[SIGMA];
    std::vector<int> idx_words;
    int cnt;
    Node()
    {
        lsp = 0;
        cnt = 0;
        idx_words.clear();
        for (int i = 0; i < SIGMA; i++) {
            to[i] = jump[i] = 0;
        }
    }
};

std::vector<Node> trie(1);
std::vector<int> ord;
void insert_word(std::string &t, int index)
{
    int now = 0;
    for (auto &c : t) {
        if (trie[now].to[c - 'a'] == 0) {
            trie[now].to[c - 'a'] = trie.size();
            trie.push_back(Node());
        }
        now = trie[now].to[c - 'a'];
    }
    trie[now].idx_words.push_back(index);
}

void bfs()
{
    std::queue<int> q;
    ord.clear();
    ord.reserve(trie.size());

    q.push(0);
    ord.push_back(0);

    while (q.size()) {
        int then = q.front();
        q.pop();
        for (int i = 0; i < SIGMA; i++) {
            if (trie[then].to[i] != 0) {
                ord.push_back(trie[then].to[i]);
                q.push(trie[then].to[i]);
            }
        }
    }
}

void build_automaton()
{
    for (int i = 0; i < SIGMA; i++) {
        trie[0].jump[i] = trie[0].to[i];
    }

    for (auto &now : ord) {
        for (int i = 0; i < SIGMA; i++) {
            if (trie[now].to[i] != 0) {
                trie[now].jump[i] = trie[now].to[i];
            } else {
                trie[now].jump[i] = trie[trie[now].lsp].jump[i];
            }
        }
        if (now > 0) {
            for (int i = 0; i < SIGMA; i++) {
                int nxt = trie[now].to[i];
                if (nxt != 0) {
                    trie[nxt].lsp = trie[trie[now].lsp].jump[i];
                }
            }
        }
    }
}

std::vector<int> query(std::string &s, int n)
{
    std::vector<int> rez(n);

    int now = 0;
    for (auto &c : s) {
        now = trie[now].jump[c - 'a'];
        trie[now].cnt++;
    }
    for (int xx = trie.size() - 1; xx > 0; xx--) {
        int i = ord[xx];
        for (auto &idx : trie[i].idx_words) {
            rez[idx] = trie[i].cnt;
        }
        trie[trie[i].lsp].cnt += trie[i].cnt;
    }

    return rez;
}

void solve()
{
    std::string s;
    std::cin >> s;
    int n;
    std::cin >> n;
    for (int i = 0; i < n; i++) {
        std::string t;
        std::cin >> t;
        insert_word(t, i);
    }
    bfs();
    build_automaton();
    auto rez = query(s, n);
    for (auto &c : rez) {
        std::cout << c << ' ';
    }
}

signed main(void)
{
    freopen("ahocorasick.in", "r", stdin);
    freopen("ahocorasick.out", "w", stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int tt = 1;
    while (tt--) {
        solve();
    }
}