Cod sursa(job #2373883)

Utilizator EricEric Vilcu Eric Data 7 martie 2019 15:38:03
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct fine{int q;fine *n;};
struct ARK{
    int v;//int INDEX;
    fine*F;fine*FE;
    ARK*nop,*a[26];
    void i0(){v=0;nop=NULL;for(int i=0;i<=25;++i)a[i]=NULL;F=FE=NULL;}
}*B=new ARK;
char t[10002],q[1000002];
int fin[101];ARK*tp[100000001];
int n;//int INDEX;
void finnd()
{
    int b=0,e=1;
    tp[0]=B;
    while(b<e)
    {
        ARK*C=tp[b];
        for(int i=0;i<=25;++i)if(C->a[i]!=NULL)
        {
            ARK*t=C->a[i];ARK*fail=C->nop;
            while(fail->a[i]==NULL&&fail!=B)fail=fail->nop;
            t->nop=fail->a[i];
            if(t->nop==t||t->nop==NULL)t->nop=B;
            else if(t->nop->F!=NULL){if(t->F!=NULL)
            {
                t->FE->n=t->nop->F;
                t->FE=t->nop->FE;
            }
            else {t->FE=t->nop->FE;t->F=t->nop->F;}
            }
            tp[e]=t;++e;
        }
        ++b;
    }
}
void addtotree(int qui)
{
    ARK *p=B;
    int i=0,n=strlen(t);
    for(;i<n;++i)
    {
        if(p->a[t[i]-'a']==NULL)
        {
            ARK*D=new ARK;
            D->i0();
            //D->INDEX=++INDEX;
            p->a[t[i]-'a']=D;
            p=D;
        }
        else p=p->a[t[i]-'a'];
    }
    fine*Q=new fine;
    Q->q=qui;
    if(p->F==NULL)
        Q->n=p->F,p->FE=p->F=Q;
    else
    {
        Q->n=p->F,p->F=Q;
    }
}
void fins(ARK*A)
{
    fine*L=A->F;
    while(L!=NULL)
    {
        fin[L->q]+=A->v;
        L=L->n;
    }
    for(int i=0;i<=25;++i)if(A->a[i]!=NULL)fins(A->a[i]);
}
int main()
{
    B->i0();//B->INDEX=-1;
    f.getline(q,1000002);
    f>>n;
    for(int i=1;i<=n;++i)
    {
        f>>t;
        addtotree(i);
    }
    B->nop=B;
    finnd();
    ARK*h=B;
    for(int i=0;q[i]>0;++i)
    {
        //cout<<h->v<<' '<<q[i]<<' '<<h->INDEX<<'\n';
        while(h!=B&&h->a[q[i]-'a']==NULL){h=h->nop;}
        if(h->a[q[i]-'a']!=NULL)h=h->a[q[i]-'a'];
        h->v+=1;
    }
    fins(B);
    for(int i=1;i<=n;++i)g<<fin[i]<<'\n';
}