Cod sursa(job #2460878)

Utilizator bluestorm57Vasile T bluestorm57 Data 24 septembrie 2019 17:13:26
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb

#include <bits/stdc++.h>

using namespace std;

ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");

const int ALF = 26;
const int NMAX = 10005;
const int LMAX = 1000005;
char s[LMAX],c[NMAX];
int n,l,last[NMAX],ic,sc, leng;

struct Trie{
    vector <int> nd;
    int nr;
    Trie *f[ALF], *fail;
    Trie(){
        nr = 0;
        fail = NULL;
        memset(f,0,sizeof(f));
    }
}*q[NMAX * NMAX], *T, *p;

void ins(Trie *node, char *p, int i){
    if(!isalpha(*p)){
        node -> nd.push_back(i);
        return;
    }
    int urm = *p - 'a';
    if(node -> f[urm] == 0)
        node -> f[urm] = new Trie;
    ins(node -> f[urm], p + 1, i);
}

void bfs(Trie *node){
    Trie *dolar;
    node -> fail = node;
    for(q[ic = sc = 1] = node ; ic <= sc ; ic++){
        Trie *fr = q[ic];
        for(int i = 0 ; i < ALF ; i++)
            if(fr -> f[i] != NULL){
                for(dolar = fr -> fail ; dolar != node && dolar -> f[i] == NULL ; dolar = dolar -> fail);

                if(dolar -> f[i] != NULL && dolar -> f[i] != fr -> f[i])
                    dolar = dolar -> f[i];
                fr -> f[i] -> fail = dolar;
                q[++sc] = fr -> f[i];
            }
    }
    node -> fail = NULL;
}

void antibfs(Trie *node){
    for(int i = sc ; i ; i--){
        Trie *fr = q[i];
        if(fr -> fail != NULL)
            fr -> fail -> nr += fr -> nr;
        for(int j = 0 ; j < fr -> nd.size() ; j++)
            last[fr -> nd[j]] = fr -> nr;
    }
}

int main(){
    int i;
    f >> s >> n;
    T = new Trie;
    for(i = 1 ; i <= n ; i++){
        f >> c;
        ins(T, c, i);
    }
    bfs(T);
    p = T;
    leng = strlen(s);
    for(i = 0 ; i < leng ; i++){
        int urm = s[i] - 'a';
        for(; p -> f[urm] == NULL && p != T ; p = p -> fail);
        if(p -> f[urm] != NULL)
            p = p -> f[urm];
        p -> nr++;
    }
    antibfs(T);
    for(i = 1 ; i <= n ; i++)
        g << last[i] << "\n";
    return 0;
}