Cod sursa(job #3304075)

Utilizator unomMirel Costel unom Data 20 iulie 2025 12:31:09
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
using namespace std;

static const int MAXS = 1000000 + 5;  // maxim noduri în trie
static const int ALPHA = 26;

int nxt[MAXS][ALPHA];
int fail[MAXS];
vector<int> outp[MAXS];
int node_cnt = 1;  // 0 = root

inline int c2i(char c) { return c - 'a'; }

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

    string A;
    in >> A;
    int lenA = (int)A.size();

    int n;
    in >> n;

    // Construim trie-ul
    for(int id = 1; id <= n; id++){
        string s;
        in >> s;
        int u = 0;
        for(size_t i = 0; i < s.size(); ++i){
            int c = c2i(s[i]);
            if(nxt[u][c] == 0){
                nxt[u][c] = node_cnt++;
            }
            u = nxt[u][c];
        }
        outp[u].push_back(id);
    }

    // BFS pentru fail + completare tranziții
    queue<int> q;
    for(int c = 0; c < ALPHA; c++){
        if(nxt[0][c] != 0){
            fail[nxt[0][c]] = 0;
            q.push(nxt[0][c]);
        }
    }
    while(!q.empty()){
        int u = q.front(); q.pop();
        for(int c = 0; c < ALPHA; c++){
            int v = nxt[u][c];
            if(v != 0){
                int f = fail[u];
                while(f != 0 && nxt[f][c] == 0){
                    f = fail[f];
                }
                fail[v] = nxt[f][c];
                // agregare output de la fail
                for(size_t k = 0; k < outp[fail[v]].size(); ++k){
                    outp[v].push_back(outp[fail[v]][k]);
                }
                q.push(v);
            } else {
                // completăm tranziția pentru căutare rapidă
                nxt[u][c] = nxt[ fail[u] ][c];
            }
        }
    }

    // Vector frecvențe
    vector<long long> freq(n+1, 0LL);

    // Parcurgem textul
    int cur = 0;
    for(int i = 0; i < lenA; i++){
        int c = c2i(A[i]);
        cur = nxt[cur][c];
        for(size_t k = 0; k < outp[cur].size(); ++k){
            freq[outp[cur][k]]++;
        }
    }

    // Scriem rezultatele
    for(int i = 1; i <= n; i++){
        out << freq[i] << "\n";
    }

    return 0;
}