Cod sursa(job #1410108)

Utilizator ArhivaArhiva Infoarena Arhiva Data 30 martie 2015 21:02:41
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int LGMAX = 1000004;
struct Trie
{
    Trie *fiu[26];
    Trie *fail;
    int sol;
    vector < int > ind;
    Trie()
    {
        sol = 0;ind.clear();
        fail = NULL;
        for(int i = 0;i < 26; ++i)
            fiu[i] = NULL;
    }
};
Trie *T = new Trie;
int n, fi, la, sol[104];
Trie *Q[1000004];
char s[LGMAX], a[10004];
inline void Add(Trie *&T,char *s,const int index)
{
    if(s[0] == 0)
    {
        T->ind.push_back(index);
        return ;
    }
    int f = s[0]-'a';
    if(T->fiu[f] == 0)
        T->fiu[f] = new Trie;
    Add(T->fiu[f],s+1,index);
}
inline void BFS()
{
    la = -1;
    for(int i = 0;i < 26; ++i)
        if(T->fiu[i]){
            Q[++la] = T->fiu[i];
            T->fiu[i]->fail = T;
        }
    while(fi<=la)
    {
        Trie *curent = Q[fi++];
        for(int i = 0;i < 26; ++i)
            if(curent->fiu[i] != 0)
            {
                Trie *Fail = curent->fail;
                while(Fail != T && Fail->fiu[i]==0)
                    Fail = Fail->fail;
                if(Fail->fiu[i] != 0)
                    Fail = Fail->fiu[i];
                curent->fiu[i]->fail = Fail;
                Q[++la] = curent->fiu[i];
            }
    }
}
int main()
{
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
    scanf("%s",(s+1));
    scanf("%d\n",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%s",a);
        Add(T,a,i);
    }
    BFS();
    Trie *curent = T;
    for(int i = 1;s[i]; ++i)
    {
        int f = s[i]-'a';
        while(curent != T && curent->fiu[f]==0)
            curent = curent->fail;
        if(curent->fiu[f] != 0)
            curent = curent->fiu[f];
        curent->sol++;
    }
    for(int i=la;i>=0;--i){
        Q[i]->fail->sol += Q[i]->sol;
        for(auto x = Q[i]->ind.begin();x != Q[i]->ind.end();++x)
            sol[*x] = Q[i]->sol;
    }
    for(int i=1;i<=n;++i)
        printf("%d\n",sol[i]);
    return 0;
}