Cod sursa(job #3340562)

Utilizator paulihno15Ciumandru Paul paulihno15 Data 14 februarie 2026 23:10:45
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 kb
/*
    Author: Paul Ciumandru
    Hard work beats talent!
*/
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000
#define MMAX 50000
#define PMAX 524288
#define LOG 18
#define INF_INT 2e9
#define INF_LL 1e18
#define BS 666013
#define MOD 1000000007

#define debug(x) cout << #x << " = " << x << "\n";
#define vdebug(a) cout << #a << " = "; for(auto x: a) cout << x << " "; cout << "\n";

#define ll long long
#define ull unsigned long long
#define dbl double
#define ldb long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define piv pair<int, vector<int>>
#define pipii pair<int, pair<pii, pii>>
#define tpl tuple<int, int, int>
#define tpl2 tuple<int, int, vector<int>>
#define vpi vector<pii>

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

int n;
int ans[NMAX + 2];
string text, wrd;

struct Aho_Corasick {
    struct TrieNode {
        TrieNode *nxt[26], *suf_link;
        int cnt = 0;
        vector<int> cuv;
        TrieNode() {
            fill(nxt, nxt + 26, nullptr);
        }
    };
    TrieNode *rad = new TrieNode();
    vector<TrieNode*> bfs_ord;

    void insert(const string &s, int ind) {
        TrieNode *nod = rad;
        for (char ch : s) {
            if (!nod -> nxt[ch - 'a']) {
                nod -> nxt[ch - 'a'] = new TrieNode();
            }
            nod = nod -> nxt[ch - 'a'];
        }
        nod -> cuv.push_back(ind);
    }

    void build() {
        queue<TrieNode*> q;
        q.push(rad);
        rad -> suf_link = rad;

        while (!q.empty()) {
            TrieNode *nod = q.front();
            q.pop();
            bfs_ord.push_back(nod);

            for (char ch = 'a'; ch <= 'z'; ch++) {
                TrieNode *child = nod -> nxt[ch - 'a'];
                if (!child) {
                    continue;
                }

                TrieNode *fall_back = nod -> suf_link;
                while (fall_back != rad && !fall_back -> nxt[ch - 'a']) {
                    fall_back = fall_back -> suf_link;
                }
                if (fall_back -> nxt[ch - 'a'] && fall_back -> nxt[ch - 'a'] != child) {
                    child -> suf_link = fall_back -> nxt[ch - 'a'];
                }
                else {
                    child -> suf_link = rad;
                }
                q.push(child);
            }
        }
    }

    void search(const string &txt) {
        TrieNode *nod = rad;
        for (char ch : txt) {
            while (nod != rad && !nod -> nxt[ch - 'a']) {
                nod = nod -> suf_link;
            }
            if (nod -> nxt[ch - 'a']) {
                nod = nod -> nxt[ch - 'a'];
            }
            nod -> cnt++;
        }

        reverse(bfs_ord.begin(), bfs_ord.end());
        for (auto it : bfs_ord) {
            for (auto ind : it -> cuv) {
                ans[ind] += it -> cnt;
            }
            it -> suf_link -> cnt += it -> cnt;
        }
    }
}aho_corasick;

int main() {
    ios_base::sync_with_stdio(false);
    fin.tie(NULL);
    fout.tie(NULL);

    fin >> text;

    fin >> n;
    for (int i = 1; i <= n; i++) {
        fin >> wrd;
        aho_corasick.insert(wrd, i);
    }

    aho_corasick.build();
    aho_corasick.search(text);

    for (int i = 1; i <= n; i++) {
        fout << ans[i] << "\n";
    }
    return 0;
}