Cod sursa(job #721384)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 23 martie 2012 17:48:11
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <stdio.h>
#include <cctype>
#include <vector>
#include <cstring>
using namespace std;
char a[1000005],b[10005];
int w[10005];
int p,u;

struct nod{
    vector<int>cuv;
    int n;
    nod*f[26];
    nod*fail;
    nod(){
        fail=NULL;
        for(int i=0;i<26;i++)f[i]=0; } }*t,*q[10005*10005],*r;

void add(nod*t,char*b,int i){
    if(*b<'a'||*b>'z'){
        t->cuv.push_back(i);
        return; }
    int urm=*b-'a';
    if(t->f[urm]==0)t->f[urm]=new nod;
    add(t->f[urm],b+1,i);
}

void bfs(nod*t){
    nod*dolar;
    t->fail=t;
    for(q[p=u=1]=t;p<=u;++p){
        nod*fr=q[p];
        for(int i=0;i<26;i++)
        if(fr->f[i]!=NULL){
        for(dolar=fr->fail;dolar!=t&&dolar->f[i]==NULL;dolar=dolar->fail);
    if(dolar->f[i]!=NULL&&dolar->f[i]!=fr->f[i])dolar=dolar->f[i];
    fr->f[i]->fail=dolar;
    q[++u]=fr->f[i]; } }
    t->fail=NULL;
}

void antibfs(nod*t){
    for(int i=u;i>0;i--){
        nod*fr=q[i];
        if(fr->fail!=NULL)fr->fail->n+=fr->n;
        for(int j=0;j<fr->cuv.size();j++)w[fr->cuv[j]]=fr->n; }
}

int main(){
    int n;
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
        scanf("%s ",a);
        scanf("%d ",&n);
    t=new nod;
    for(int i=1;i<=n;i++){
        scanf("%s",b);
        add(t,b,i);}
    bfs(t);
    r=t;
    int lg=strlen(a);
    for(int i=0;i<lg;i++){
        int urm=a[i]-'a';
        for(;r->f[urm]==NULL&&r!=t;r=r->fail);
        if(r->f[urm]!=NULL)r=r->f[urm];
        ++r->n; }
    antibfs(t);
    for(int i=1;i<=n;i++)printf("%d\n",w[i]);
}