Cod sursa(job #1920284)

Utilizator blatulInstitutul de Arta Gastronomica blatul Data 9 martie 2017 23:27:25
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>

using namespace std;

struct Trie {
    Trie* next[26];
    Trie* fail;
    int frequency;
};

Trie* Insert(Trie*& root, const string& word) {
    Trie* node = root;
    for(int i = 0; i < (int)word.size(); ++i) {
        if(node->next[word[i] - 'a'] == NULL) 
            node->next[word[i] - 'a'] = new Trie();
            
        node = node->next[word[i] - 'a'];
    }
    return node;
}

Trie* Q[1000005];

int main() {
    #ifdef INFOARENA
    ifstream cin("ahocorasick.in");
    ofstream cout("ahocorasick.out");
    #endif
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    
    string a; 
    cin >> a;
    
    Trie* root = new Trie();
    
    int n; 
    cin >> n;
    vector<Trie*> Link(n);
    for(int i = 0; i < n; ++i) {
        string word;
        cin >> word;
        
        Link[i] = Insert(root, word);
    }
    
    int qStart = 0, qEnd = 0;
    root->fail = root;
    for(int i = 0; i < 26; ++i)
        if(root->next[i] != NULL) {
            root->next[i]->fail = root;
            Q[qEnd++] = root->next[i];
        }
        
    while(qStart != qEnd) {
        Trie* node = Q[qStart++];
        
        for(int i = 0; i < 26; ++i) if(node->next[i]) {
            Trie* son = node->next[i];
            Trie* aux = node->fail;
            
            while(aux != root && aux->next[i] == NULL)
                aux = aux->fail;
            
            if(aux->next[i])
                son->fail = aux->next[i];
            else 
                son->fail = root;
                
            Q[qEnd++] = son;
        }
    }
    
    Trie* node = root;
    for(const char& ch: a) {
        while(node != root && node->next[ch - 'a'] == NULL)
            node = node->fail;
            
        if(node->next[ch - 'a'])
            node = node->next[ch - 'a'];
        
        node->frequency++;
    }
    
    for(int i = qEnd - 1; i >= 0; --i)
        Q[i]->fail->frequency += Q[i]->frequency;
        
    for(int i = 0; i < n; ++i)
        cout << Link[i]->frequency << '\n';
}