Cod sursa(job #2376552)

Utilizator dacianouaPapadia Mortala dacianoua Data 8 martie 2019 16:18:59
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <fstream>
#include <string.h>
#include <deque>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
char text[1000005],cuv[10005];
int n, p[105],val[105];
struct trie
{
    int val,k;
    trie *fiu[26],*fail;
    trie()
    {
        val=k=0;
        fail=0;
        memset(fiu,0,sizeof(fiu));
    }
}*root,*nod,*f;
deque<trie*> q1,q2;
void adauga(char *s,int k)
{
    nod=root;
    while(*s)
    {
        if(!nod->fiu[s[0]-'a'])
            nod->fiu[s[0]-'a']=new trie;
        nod=nod->fiu[s[0]-'a'];
        s++;
    }
    if(!nod->k)
        nod->k=k;
    p[k]=nod->k;
}
void link()
{
    root->fail=root;
    for(int i=0;i<26;i++)
        if(root->fiu[i])
        q1.push_back(root->fiu[i]),root->fiu[i]->fail=root;
    while(!q1.empty())
    {
        nod=q1.front();
        q1.pop_front();
        q2.push_back(nod);
        for(int i=0;i<26;i++)
            if(nod->fiu[i])
            {
                f=nod->fail;
                while(f!=root && !f->fiu[i])
                    f=f->fail;
                if(f->fiu[i])
                    nod->fiu[i]->fail=f->fiu[i];
                else
                    nod->fiu[i]->fail=root;
                q1.push_back(nod->fiu[i]);
            }
    }
}
void match(char *txt)
{
    nod=root;
    while(*txt)
    {
        while(nod!=root && !nod->fiu[txt[0]-'a'])
            nod=nod->fail;
        if(nod->fiu[txt[0]-'a'])
            nod=nod->fiu[txt[0]-'a'];
        nod->val++;
        txt++;
    }
}
void solve()
{
    while(!q2.empty())
    {
        nod=q2.back();
        q2.pop_back();
        nod->fail->val+=nod->val;
        if(!val[nod->k])
            val[nod->k]=nod->val;
    }
}
int main()
{
    fin>>text;
    fin>>n;
    root=new trie;
    for(int i=1;i<=n;i++)
    {
        fin>>cuv;
        adauga(cuv,i);
    }
    link();
    match(text);
    solve();
    for(int i=1;i<=n;i++)
        fout<<val[p[i]]<<"\n";
    return 0;
}