Cod sursa(job #2267088)

Utilizator andrei_diaconu11Andrei C. Diaconu andrei_diaconu11 Data 23 octombrie 2018 11:15:15
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.13 kb
#include <bits/stdc++.h>
#define MAXN 100
#define MAXM 1000000
#define SIGMA 26

struct Trie{
    int cnt;
    Trie *son[SIGMA];
    Trie *fail;
    std::vector <int> word;

    Trie(){
        word.clear();
        cnt = 0;
        memset(son, 0, sizeof(son));
    }
};

Trie *T = new Trie();
Trie *S;
std::queue <Trie*> q;
std::stack <Trie*> p;
int n, m;
char v[1 + MAXM];
int ans[1 + MAXN];
int main(){
    FILE*fi,*fo;
    fi = fopen("ahocorasick.in","r");
    fo = fopen("ahocorasick.out","w");

    char c = fgetc(fi);
    while('a' <= c && c <= 'z'){
        v[++m] = c - 'a';
        c = fgetc(fi);
    }

    fscanf(fi,"%d", &n);
    c = fgetc(fi);
    for(int i = 1; i <= n; i++){
        while(c < 'a' || c > 'z') c = fgetc(fi);
        S = T;
        while('a' <= c && c <= 'z'){
            c -= 'a';
            if(!S -> son[c])
                S -> son[c] = new Trie();
            S = S -> son[c];
            c = fgetc(fi);
        }
        S -> word.push_back(i);
    }

    for(int i = 0; i < SIGMA; i++)
        if(T -> son[i]){
            T -> son[i] -> fail = T;
            q.push(T -> son[i]);
        }
    while(!q.empty()){
        Trie *node = q.front(); q.pop();
        p.push(node);
        for(int i = 0; i < SIGMA; i++)
            if(node -> son[i]){
                Trie *fail = node;
                do{
                    fail = fail -> fail;
                }while(fail != T && !fail -> son[i]);
                if(fail -> son[i])
                    fail = fail -> son[i];
                node -> son[i] -> fail = fail;
                q.push(node -> son[i]);
            }
    }

    S = T;
    for(int i = 1; i <= m; i++){
        while(S != T && !S -> son[v[i]])
            S = S -> fail;
        if(S -> son[v[i]])
            S = S -> son[v[i]];
        S -> cnt++;
    }

    while(!p.empty()){
        Trie *node = p.top(); p.pop();
        node -> fail -> cnt += node -> cnt;
        for(auto y: node -> word)
            ans[y] = node -> cnt;
    }

    for(int i = 1; i <= n; i++)
        fprintf(fo,"%d\n", ans[i]);

    return 0;
}