Cod sursa(job #759736)

Utilizator test13test13 test13 Data 19 iunie 2012 00:31:04
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

struct dic{
    struct dic *f[26]; // fii
    struct dic *fail; // urcam in sus
    vector<int>cuv;
    int nr;
}*t,*cd[1000001];

int n,x[101],u;
char a[1000001],b[10001];

void adauga(int k,char *b){
    dic *g=t;
    int urm;
    while('a'<=*b && *b<='z')
    {
        urm=*b-'a';
        if(g->f[urm]==0)g->f[urm]=new dic;
        g=g->f[urm];
        b++; // trecem la urmatorul caracter
    }
        g->cuv.push_back(k); // introducem cuvintul nou
}

void bfs(){
    dic *g,*v;
    int p,x;
    cd[p=u=1]=t;
    t->fail=t;
    while(p<=u)
    {
        g=cd[p];
        for(int i=0;i<26;i++)
        if(g->f[i])
        {
            for(v=g->fail; v!=t && v->f[i] == 0; v=v->fail);
            if(v->f[i] != 0 && v->f[i] != g->f[i])v=v->f[i];
            g->f[i]->fail=v;
            cd[++u]=g->f[i]; //introducem nodul in coada
        }
        p++; // mergem la nodul urmator
    }
    t->fail=0;
}

void ahocorasick(){
    char *b=a;
    int urm;
    dic *g=t;
    while('a'<=*b && *b<='z')
    {
        urm=*b-'a';
        while(g!=t && g->f[urm] == 0)g=g->fail;
        if(g->f[urm] != 0)g=g->f[urm];
        g->nr++;
        //printf("%c",*b);
        b++;
    }
}

void antibfs(){
    dic *g;
    while(u>0)
    {
        g=cd[u--];
        if(g->fail!=0)g->fail->nr += g->nr;
        for(int i=0;i<g->cuv.size();i++){ x[g->cuv[i]]=g->nr; }
    }
}

int main(){
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
        scanf("%s ",a);
        scanf("%d ",&n);
    t=new dic; // cream structura
        for(int i=1;i<=n;i++)
        {
            scanf("%s ",b);
            adauga(i,b);
        }
    bfs();
    ahocorasick();
    antibfs();
    for(int i=1;i<=n;i++)printf("%d\n",x[i]);
    return 0;
}