Cod sursa(job #1455582)

Utilizator heracleRadu Muntean heracle Data 28 iunie 2015 15:25:59
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <cstdio>
#include <vector>
#include <cstring>

FILE* in=fopen("ahocorasick.in","r");
FILE* out=fopen("ahocorasick.out","w");


const int Q=1000007,W=10007;

struct trie
{
    std::vector<int> fin;
    trie* go[26];
    trie* rt;
    int vizite;
    trie()
    {
        vizite=0;
        for(int i=0; i<26; i++)
            go[i]=NULL;
        rt=NULL;
    }
} *start;


std::vector<trie*> lv[W];

int rez[W];

void decoder()
{
    for(int k=10002; k>0; k--)
    {
        for(int i=0; i<lv[k].size(); i++)
        {
            lv[k][i]->rt->vizite+=lv[k][i]->vizite;

            for(int f=0; f<lv[k][i]->fin.size(); f++)
            {
                rez[lv[k][i]->fin[f]]=lv[k][i]->vizite;
            }
        }
    }
}

char v[Q];

void parcurgere()
{
    int s=strlen(v);

    while(v[s]>'z' || v[s]<'a')
        s--;

    trie *act=start;

    for(int i=0; i<=s; i++)
    {
        while(act!=start && act->go[v[i]-'a']==NULL)
            act=act->rt;
        if(act->go[v[i]-'a']!=NULL)
            act=act->go[v[i]-'a'];
        act->vizite++;
    }
}


void make_fail()
{
    start->rt=start;

    for(int i=0; i<26; i++)
    {
        if(start->go[i]!=NULL)
        {
            start->go[i]->rt=start;
        }
    }

    for(int k=2; lv[k].size()!=0; k++)
    {
        for(int i=0; i<lv[k].size(); i++)
        {
            for(int f=0; f<26; f++)
            {
                if(lv[k][i]->go[f]!=NULL)
                {
                    trie *p=lv[k][i]->rt;

                    while(p!=start && p->go[f]==NULL)
                        p=p->rt;

                    if(p->go[f]!=NULL)
                    {
                        lv[k][i]->go[f]->rt=p->go[f];
                    }
                    else
                    {
                        lv[k][i]->go[f]->rt=start;
                    }
                }
            }
        }
    }
}

trie *add(trie *nod, char c[], int who, int pas)
{
    if(nod==NULL)
    {
        nod=new trie;
        lv[pas].push_back(nod);
    }

    if(c[0]==0 || c[0]=='\n')
    {
        nod->fin.push_back(who);
        return nod;
    }

    nod->go[c[0]-'a']=add(nod->go[c[0]-'a'],c+1,who,pas+1);
    return nod;
}



char c[W];

int main()
{

    fgets(v,Q,in);

    int n;

    fscanf(in,"%d\n",&n);

    for(int i=1; i<=n; i++)
    {
        fgets(c,W,in);

        start=add(start,c,i,1);
    }


    make_fail();

    parcurgere();

    decoder();

    for(int i=1; i<=n; i++)
    {
        fprintf(out,"%d\n",rez[i]);
    }

    return 0;
}