Cod sursa(job #2985526)

Utilizator Tudor_MateiHolota Tudor Matei Tudor_Matei Data 26 februarie 2023 16:18:19
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.73 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>

using namespace std;

const int MAXN = 1000100, MAXM = 10010;

int trie[MAXN][26], fail[MAXN], wordCnt[MAXN];
vector<int> wordEnd[MAXN];
int trieSize = 1;

void addWord(string &word, int wordId) {
    int node = 0;
    for (char c : word) {
        int child = trie[node][c - 'a'];
        if (child == 0) {
            trie[node][c - 'a'] = trieSize;
            child = trieSize++;
        }
        node = child;
    }
    wordEnd[node].push_back(wordId);
}

void buildFailLinks() {
    queue<int> q;
    for (int i = 0; i < 26; i++) {
        int child = trie[0][i];
        if (child != 0) {
            q.push(child);
        }
    }

    while (!q.empty()) {
        int node = q.front();
        q.pop();
        for (int i = 0; i < 26; i++) {
            int child = trie[node][i];
            if (child != 0) {
                fail[child] = trie[fail[node]][i];
                q.push(child);
            } else {
                trie[node][i] = trie[fail[node]][i];
            }
        }
        for (int w : wordEnd[fail[node]]) {
            wordEnd[node].push_back(w);
        }
    }
}

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

    string A;
    int n;
    fin >> A >> n;
    vector<string> words(n);
    for (int i = 0; i < n; i++) {
        fin >> words[i];
        addWord(words[i], i);
    }

    buildFailLinks();

    int node = 0;
    for (char c : A) {
        node = trie[node][c - 'a'];
        for (int w : wordEnd[node]) {
            wordCnt[w]++;
        }
    }

    for (int i = 0; i < n; i++) {
        fout << wordCnt[i] << '\n';
    }

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