Cod sursa(job #2488956)

Utilizator AlexBolfaAlex Bolfa AlexBolfa Data 7 noiembrie 2019 20:20:45
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int CMAX=30;
const int NMAX=104;
struct trie{
    int cnt;
    trie* child[CMAX];
    trie* suffix;
    vector <int> words;
    trie(){
        cnt=0;
        suffix=0;
        memset(child, 0, sizeof child);
    }
};

int n,frq[NMAX];
trie* root = new trie();
string s,a;
queue <trie*> q;
vector <trie*> anti;

void read();
void bfs();
void dfs(trie*);
void aho();
void antibfs();
void print();
void updade(trie,string::iterator,int);

int main(){
    read();
    bfs();
    aho();
    antibfs();
    print();
    return 0;
}
void antibfs(){
    reverse(anti.begin(), anti.end());
    for(auto it:anti){
        it->suffix->cnt += it->cnt;
        for(auto w: it->words) frq[w]=it->cnt;
    }
}
void aho(){
    int c;
    trie* node=root;
    trie* t;

    for(int i=0;i<s.size();++i){
        c=s[i]-'a';
        if(node->child[c])
            node=node->child[c];
        else{
            for(t=node->suffix; !(t->child[c]) && t!=root; t=t->suffix);

            if(t->child[c])
                t=t->child[c];
            node=t;
        }
       ++node->cnt;
    }
}
void bfs(){
    trie* node, *t;
    root->suffix=root;
    q.push(root);

    while(!q.empty()){
        node=q.front();
        q.pop();

        for(int i=0;i<CMAX;++i){
            if(!(node->child[i]))
                continue;
            anti.push_back(node->child[i]);
            q.push(node->child[i]);

            for(t=node->suffix; !(t->child[i]) && t!=root; t = t->suffix);

            if(t->child[i] && node != root)
                t=t->child[i];

            node->child[i]->suffix=t;
        }
    }
}
void update(trie* node, string::iterator it, int id){
    while(it != a.end()){
        int c=*it-'a';

        if(!(node->child[c])) node->child[c] = new trie();

        node= node->child[c];
        ++it;
    }
    node->words.push_back(id);
}
void read(){
    fin>>s>>n;
    for(int i=1;i<=n;++i){
        fin>>a;
        update(root, a.begin(), i);
    }
}
void print(){
    for(int i=1;i<=n;++i)
        fout<<frq[i]<<'\n';
}