Cod sursa(job #1979172)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 9 mai 2017 20:34:57
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <fstream>
#include <cstring>
#include <vector>
#define Nmax 1000001
#define Cmax 10001
using namespace std;

ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");

int n,L,R,rez[Cmax];
char s[Nmax],c[Cmax];

struct trie{
    vector<int> v;
    int val;
    int ap;
    trie *f[26],*fail;

    trie(int _val,int _ap) : val(_val) , ap(_ap)
    {
        memset(f,0,sizeof(f));
        fail = NULL;
    }
}*T,*st[Cmax*101];

void add(char c[],int x)
{
    int lg = strlen(c);
    trie *nod;
    nod = T;
    for (int i=0;i<lg;i++)
    {
        if (nod->f[c[i]-'a']==NULL)
            nod->f[c[i]-'a'] = new trie(0,0);
        nod = nod->f[c[i]-'a'];
    }
    nod->v.push_back(x);
}

void bfs()
{
    trie *nod;
    R = 0;
    st[0] = T;
    T->fail = T;
    for (int i=0;i<=R;i++)
    {
        for (int lit=0;lit<26;lit++)
        {
            if (st[i]->f[lit]!=NULL)
            {
                nod = st[i]->fail;
                while (nod->f[lit]==NULL && nod!=T)
                    nod = nod->fail;
                if (nod->f[lit]!=NULL && nod->f[lit]!=st[i]->f[lit])
                    nod = nod->f[lit];
                st[i]->f[lit]->fail = nod;
                st[++R] = st[i]->f[lit];
            }
        }
    }
}

void bfs2()
{
    for (int i=R;i>=0;i--)
    {
        if (st[i]->fail!=NULL)
            st[i]->fail->val += st[i]->val;
        for (int j=0;j<(int)st[i]->v.size();j++)
        {
            rez[st[i]->v[j]] += st[i]->val;
        }
    }
}



int main()
{
    f>>s;
    f>>n;
    T = new trie(0,0);
    for (int i=1;i<=n;i++)
    {
        f>>c;
        add(c,i);
    }

    bfs();

    int lg = strlen(s);
    trie *nod = T;
    for (int i=0;i<lg;i++)
    {
        while (nod->f[s[i]-'a']==NULL && nod!=T)
        {
            nod = nod->fail;
        }
        if (nod->f[s[i]-'a']!=NULL)
            nod = nod->f[s[i]-'a'];
        nod->val++;
    }

    bfs2();

    for (int i=1;i<=n;i++)
        g<<rez[i]<<'\n';


    return 0;
}