Cod sursa(job #788886)

Utilizator round2Test P round2 Data 16 septembrie 2012 00:12:15
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include <cstdio>
#include <cctype>
#include <cstring>
#include <vector>
using namespace std;

struct trie{
    struct trie*f[26];
    struct trie*fail;
    vector<int>c;
    int nr;
    trie()
    {
        memset(f,0,sizeof(f));
        fail=0;
        nr=0;
        c.resize(0);
    } }*t,*cd[1000001];
char a[1000001],b[10001];
int n,num[101],u;

void adaug(char *b,int i)
{
    trie *g=t;
    int urm;
    while(isalpha(*b))
    {
        urm=*b-'a';
        if(g->f[urm]==0)g->f[urm]=new trie;
        g=g->f[urm];
        b++;
    }
        g->c.push_back(i);
}

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

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

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

int main()
{
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
        scanf("%s ",a);
        scanf("%d ",&n);
        t=new trie;
        for(int i=1;i<=n;i++)
        {
            scanf("%s ",b);
            adaug(b,i);
        }
    bfs();
    ahocorasick(a);
    antibfs();

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

    return 0;
}