Cod sursa(job #785431)

Utilizator round1First Round round1 Data 9 septembrie 2012 00:14:37
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <cstdio>
#include <vector>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;

struct trie{
    struct trie *f[26]; //fii
    struct trie *fail; // intoarcere
    vector<int>cuv;
    int nr; // <----- astai plina cu cacat
} *t,*c[1000001]; //arborele

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

int add(char *b,int k)
{
    trie *g = t;
    int urm;
    while( isalpha(*b) )
    {
        urm = *b - 'a';
        /*
        if(g->f[urm] != 0)
        {
            printf("fUCKK!!!");
            return 0;
        } */
        if( g->f[urm] == NULL )
        {
            g->f[urm] = new trie;
            //for(int i=0;i<26;i++)g->f[urm]->f[i] = NULL;
            memset(g->f[urm]->f,0,sizeof(g->f[urm]->f));
            //g->f[urm]->nr = 0;
        }
        g = g->f[urm];
        b++;
    }
        g->cuv.push_back(k);
   // printf("%d\n",k);
   return 1;
}

void bfs()
{
    trie * fr, *d;
    int p;
    t->fail = t;
    //memset(c,0,sizeof(c));
    c[p = u = 1] = t;
    while( p <= u)
    {
        fr = c[p++];
        for(int i=0;i<26;i++)
        if(fr->f[i])
        {
            for(d = fr->fail;d != t && d->f[i] == NULL;d = d->fail);
            if( d->f[i]!= 0 && d->f[i] != fr->f[i])d = d->f[i];
            fr->f[i]->fail = d;
            c[++u] = fr->f[i];
        }
    }
    t->fail = t;
}

void ahocorasick(char *b)
{
    trie *g = t;
    int urm;
    while( isalpha(*b) )
    {
        urm = *b - 'a';
        while(g != t && g->f[urm] == NULL)g = g->fail;
        if(g->f[urm] != NULL)g = g->f[urm];
        g->nr++;
        b++;
    }
}

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

int main(){
    int n;
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);

        scanf("%s ",a);
        scanf("%d ",&n);


    t = new trie;
    memset(t->f,0,sizeof(t->f));
  //  t->nr = 0;

    for(int i=1;i<=n;i++)
    {
        scanf("%s ",b);
        if(add(b,i) == 0)return 0;
        //printf("%s\n",b);
    }
    bfs();
    ahocorasick(a);
    antibfs();

    for(int i=1;i<=n;i++)printf("%d\n",num[i]);

    return 0;
}