Cod sursa(job #3298425)

Utilizator BuzdiBuzdugan Rares Andrei Buzdi Data 29 mai 2025 17:46:15
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.17 kb
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define ll long long
#define ld long double

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

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

const int KMAX = 5e5;
const int CMAX = 26;
const int INF = 1e9;

struct Node {
    int children[CMAX];
    int back_fail_node;
    int frequency;
    vector<int> indexes;

    Node() {
        for(int i = 0; i < CMAX; i++) {
            children[i] = -1;
        }
        back_fail_node = -1;
        frequency = 0;
    }
};

struct AhoCorasick {
    vector<Node> nodes;

    AhoCorasick() {
        nodes.push_back(Node());
    }

    int create_node() {
        int index = nodes.size();
        nodes.push_back(Node());
        return index;
    }
    
    void BFS() {
        queue<int> q;
        nodes[0].back_fail_node = 0;
        for(int i = 0; i < CMAX; i++) {
            int next_node = nodes[0].children[i];
            if(next_node != -1) {
                nodes[next_node].back_fail_node = 0;
                q.push(next_node);
            }
            else {
                nodes[0].children[i] = 0;
            }
        }

        while(!q.empty()) {
            auto node = q.front();
            q.pop();

            for(int i = 0; i < CMAX; i++) {
                int next_node = nodes[node].children[i];
                if(next_node != -1) {
                    nodes[next_node].back_fail_node = nodes[nodes[node].back_fail_node].children[i];
                    for(int index : nodes[nodes[next_node].back_fail_node].indexes) {
                        nodes[next_node].indexes.push_back(index);
                    }
                    q.push(next_node);
                }
                else {
                    nodes[node].children[i] = nodes[nodes[node].back_fail_node].children[i];
                }
            }
        }
    }

    void search(string& s, int answer[]) {
        int node = 0;
        for(int i = 0; i < (int) s.size(); i++) {
            node = nodes[node].children[s[i] - 'a'];
            for(int index : nodes[node].indexes) {
                answer[index]++;
            }
        }
    }

    void insert(string& s, int i) {
        int node = 0;
        for(char x : s) {
            if(nodes[node].children[x - 'a'] == -1) {
                nodes[node].children[x - 'a'] = create_node();
            }
            node = nodes[node].children[x - 'a'];
        }
        nodes[node].indexes.push_back(i);
    }

    void compute_answer(string& s, int answer[]) {
        BFS();
        search(s, answer);
    }
}aho;

int k;
int answer[KMAX + 1];
string s;

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

    fin >> s >> k;
    for(int i = 1; i <= k; i++) {
        string x;
        fin >> x;
        aho.insert(x, i);
    }

    aho.compute_answer(s, answer);
    for(int i = 1; i <= k; i++) {
        fout << answer[i] << '\n';
    }

    return 0;
}