Cod sursa(job #2029204)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 29 septembrie 2017 17:36:02
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.26 kb
#include <bits/stdc++.h>

const int MAXA = (int) 1e6;
const int MAXB = (int) 1e4;
const int MAXN = 100;
const int SIGMA = 26;

char A[MAXA + 1], B[MAXB + 1];

int sol[MAXN + 1];

struct Aho {
    Aho *son[SIGMA];
    Aho *fail;
    int cnt;
    std::vector <int> pos;
    Aho() {
         memset(son, NULL, sizeof(son));
         fail = NULL;
         cnt = 0;
    }
};

Aho *root = new Aho;

void insert(Aho *nod, char *str, int p) {
    if(*str == '\n')
        nod -> pos.push_back(p);
    else {
        if(nod -> son[*str - 'a'] == NULL)
           nod -> son[*str - 'a'] = new Aho;
        insert(nod -> son[*str - 'a'], str + 1, p);
    }
}

Aho *q[MAXA + 1];

int b = 0, e = 1;

inline void bfs() {
    q[0] = root;
    root -> fail = root;
    while(b < e) {
        Aho *nod = q[b];
        b++;
        for(int i = 0; i < SIGMA; i++)
            if(nod -> son[i] != NULL) {
                Aho *aux = nod -> fail;
                while(aux != root && aux -> son[i] == NULL)
                    aux = aux -> fail;
                if(aux -> son[i] != NULL && aux != nod)
                    nod -> son[i] -> fail = aux -> son[i];
                else
                    nod -> son[i] -> fail = aux;
                q[e++] = nod -> son[i];
            }
    }
}

inline void solve() {
    int i = 0;
    Aho *nod = root;
    while(A[i] != '\n') {
         while(nod != root && nod -> son[A[i] - 'a'] == NULL)
            nod = nod -> fail;
         if(nod -> son[A[i] - 'a'] != NULL) {
            nod = nod -> son[A[i] - 'a'];
            nod -> cnt++;
         }
         i++;
    }
}

inline void antibfs() {
    for(int i = e - 1; i >= 0; i--) {
         Aho *nod = q[i];
         for(auto it : nod -> pos)
             sol[it] += nod -> cnt;
         nod -> fail -> cnt += nod -> cnt;
    }
}

int main(){
    FILE *fi, *fout;
    int i, n, sz;
    fi = fopen("ahocorasick.in" ,"r");
    fout = fopen("ahocorasick.out" ,"w");
    fscanf(fi,"%s " ,A);
    sz = strlen(A);
    A[sz] = '\n';
    fscanf(fi,"%d " ,&n);
    for(i = 1; i <= n; i++) {
       fscanf(fi,"%s " ,B);
       sz = strlen(B);
       B[sz] = '\n';
       insert(root, B, i);
    }
    bfs();
    solve();
    antibfs();
    for(i = 1; i <= n; i++)
        fprintf(fout,"%d\n" ,sol[i]);
    fclose(fi);
    fclose(fout);
    return 0;
}