Cod sursa(job #3241431)

Utilizator Gergo123Schradi Gergo Gergo123 Data 30 august 2024 09:50:08
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstring>
#include <cctype>
#define DL 1000005
#define DN 10005
#define DA 26 

using namespace std;

int lg, n, l, final[DN], ic, sc;
string tx, c;

struct ac {
    vector<int> nd; 
    int n0; 
    ac* f[DA];
    ac* fail;

    ac() {
        n0 = 0;
        fail = nullptr;
        memset(f, 0, sizeof(f));
    }
} * q[DN * DN], * t, * p;

void ins(ac* t, const string& p, int i) {
    ac* current = t;
    for (char ch : p) {
        if (!isalpha(ch)) {
            current->nd.push_back(i);
            return;
        }
        int urm = ch - 'a';
        if (current->f[urm] == nullptr) {
            current->f[urm] = new ac;
        }
        current = current->f[urm];
    }
    current->nd.push_back(i);
}

void bfs(ac* t) {
    ac* dolar;
    t->fail = t;
    q[ic = sc = 1] = t;
    
    while (ic <= sc) {
        ac* fr = q[ic++];
        for (int i = 0; i < DA; ++i) {
            if (fr->f[i] != nullptr) {
                dolar = fr->fail;
                while (dolar != t && dolar->f[i] == nullptr) {
                    dolar = dolar->fail;
                }
                if (dolar->f[i] != nullptr && dolar->f[i] != fr->f[i]) {
                    dolar = dolar->f[i];
                }
                fr->f[i]->fail = dolar;
                q[++sc] = fr->f[i];
            }
        }
    }
    t->fail = nullptr;
}

void antibfs(ac* t) {
    for (int i = sc; i > 0; --i) {
        ac* fr = q[i];
        if (fr->fail != nullptr) {
            fr->fail->n0 += fr->n0;
        }
        for (int j : fr->nd) {
            final[j] = fr->n0;
        }
    }
}

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

    fin >> tx;
    fin >> n;

    t = new ac;
    for (int i = 1; i <= n; ++i) {
        fin >> c;
        ins(t, c, i);
    }

    bfs(t);

    p = t;
    lg = tx.length();
    for (int i = 0; i < lg; ++i) {
        int urm = tx[i] - 'a';
        while (p->f[urm] == nullptr && p != t) {
            p = p->fail;
        }
        if (p->f[urm] != nullptr) {
            p = p->f[urm];
        }
        ++p->n0;
    }

    antibfs(t);

    for (int i = 1; i <= n; ++i) {
        fout << final[i] << endl;
    }

    return 0;
}