Cod sursa(job #2763829)

Utilizator valentinchipuc123Valentin Chipuc valentinchipuc123 Data 17 iulie 2021 02:52:07
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.98 kb
#include <bits/stdc++.h>

using namespace std;

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

string s,sir;
int n,sol[1000005],st,dr;

struct trie
{
    vector<int>elem;
    int nr;
    trie *litere[26],*fail;

    trie()
    {
        nr=0;
        fail=NULL;
        memset(litere,NULL,sizeof(litere));
    }
} *coada[1000*1000],*rad,*p;

void insereaza(trie *nod,int poz,int i)
{
    if( sir.size()==poz )
    {
        nod->elem.push_back(i);
        return;
    }
    int nxt=sir[poz]-'a';

    if( nod->litere[nxt]==NULL ) nod->litere[nxt]=new trie;
    insereaza(nod->litere[nxt],poz+1,i);
}

void bfs(trie *nod)
{
    trie *nxt;
    rad->fail=nod;

    st=dr=1;
    coada[1]=nod;

    while( st<=dr )
    {
        trie *aux=coada[st];

        for(int i=0; i<26; i++)
        {
            if( aux->litere[i]!=NULL )
            {
                for(nxt=aux->fail; nxt!=rad&&nxt->litere[i]==NULL; nxt=nxt->fail);

                if( nxt->litere[i]!=NULL && nxt->litere[i]!=aux->litere[i] ) nxt=nxt->litere[i];
                aux->litere[i]->fail=nxt;
                coada[++dr]=aux->litere[i];
            }
        }

        st++;
    }
}


void antibfs(trie *nod)
{
    for(int i=dr; i>0; --i)
    {
        trie *aux=coada[i];
        if(aux->fail!=NULL) aux->fail->nr+=aux->nr;
        for(int j=0; j<aux->elem.size(); ++j) sol[aux->elem[j]]=aux->nr;
    }
}

int main()
{
    f.tie(0)->sync_with_stdio(0);
    f.tie(NULL);
    g.tie(NULL);

    f>>s;
    f>>n;

    rad=new trie;
    for(int i=1; i<=n; i++)
    {
        f>>sir;
        insereaza(rad,0,i);
    }

    bfs(rad);

    int m=s.size();
    p=rad;

    for(int i=0; i<m; ++i)
    {
        int urm=s[i]-'a';
        for(; p->litere[urm]==NULL && p!=rad; p=p->fail);
        if(p->litere[urm]!=NULL) p=p->litere[urm];
        ++p->nr;
    }

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

    return 0;
}