Cod sursa(job #3236303)

Utilizator BuzdiBuzdugan Rares Andrei Buzdi Data 27 iunie 2024 19:05:05
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.1 kb
#include <fstream>
#include <queue>
#include <vector>
#define ll long long

using namespace std;

ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");

const int NMAX = 100 * 10000;
const int CMAX = 26;

string s;
int n;
int nodes = 1;
int trie[NMAX + 1][CMAX];
int fail[NMAX + 1];
int seen[NMAX + 1];
int answer[NMAX + 1], answer_node[NMAX + 1];
vector<int> leafs[NMAX + 1], G[NMAX + 1];

void AddWord(string &word, int index) {
    int node = 1;
    for(char x : word) {
        if(!trie[node][x - 'a']) {
            trie[node][x - 'a'] = ++nodes;
        }
        node = trie[node][x - 'a'];
    }
    leafs[node].push_back(index);
}

void BFS() {
    queue<int> Q;
    fail[1] = 1;
    for(int i = 0; i < CMAX; i++) {
        if(trie[1][i]) {
            fail[trie[1][i]] = 1;
            Q.push(trie[1][i]);
        }
        else {
            trie[1][i] = 1;
        }
    }

    while(!Q.empty()) {
        int node = Q.front();
        Q.pop();

        for(int i = 0; i < CMAX; i++) {
            if(trie[node][i]) {
                fail[trie[node][i]] = trie[fail[node]][i];
                Q.push(trie[node][i]);
            }
            else {
                trie[node][i] = trie[fail[node]][i];
            }
        }
    }

    for(int i = 2; i <= nodes; i++) {
        G[fail[i]].push_back(i);
    }
}

void Search() {
    int node = 1;
    for(char x : s) {
        node = trie[node][x - 'a'];
        seen[node]++;
    }
}

void DFS(int node = 1) {
    answer_node[node] = seen[node];
    for(int next_node : G[node]) {
        DFS(next_node);
        answer_node[node] += answer_node[next_node];
    }
    for(int index : leafs[node]) {
        answer[index] = answer_node[node];
    }
}

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

    cin >> s >> n;
    for(int i = 1; i <= n; i++) {
        string word;
        cin >> word;
        AddWord(word, i);
    }

    BFS();
    Search();
    DFS();

    for(int i = 1; i <= n; i++) {
        cout << answer[i] << '\n';
    }

    return 0;
}