Cod sursa(job #785416)

Utilizator round1First Round round1 Data 8 septembrie 2012 23:31:37
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <cstdio>
#include <cctype>
#include <vector>
using namespace std;

struct trie{
    struct trie *f[26];
    struct trie *fail;
    vector<int>cuv;
    int nr; }*t,*cd[1000001];

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

void add(char *b,int x){
    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->cuv.push_back(x);
}

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

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

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

int main(){

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

    return 0;
}