Cod sursa(job #739233)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 22 aprilie 2012 14:39:50
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <cstdio>
#include <vector>
#define MAX 1000005
using namespace std;

struct arb{
    int n;
    vector<int>cuv;
    struct arb*fail,*f[26];
    arb(){ fail=0; for(int i=0;i<26;i++)f[i]=0; n=0; }
}*t,*cd[MAX];

char a[MAX],b[MAX],c[MAX];
int n,u,w[MAX];

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

void parc(arb*nod,int niv){
    for(int i=0;i<26;i++)
    if(nod->f[i]!=NULL)
    { c[niv]=i+'a'; parc(nod->f[i],niv+1); }
    if(nod->cuv.size()>0){
    c[niv]='\n'; c[niv+1]='\0';
    printf("%d",nod->n);}
}

void bfs(){
    int p;
    arb*fr,*dir;
    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]; }
    p++; }
    t->fail=0;
}

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

int main(){
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
    fgets(a,MAX,stdin);
    t=new arb;
    scanf("%d ",&n);
        for(int i=1;i<=n;i++){
            fgets(b,MAX,stdin);
        add(b,i);
        }
    bfs();
   // printf("%d\n",u);
    arb*r=t;
    int i=0,urm;
    while(a[i]>='a'&&a[i]<='z'){
        urm=a[i]-'a';
        while(r!=t&&r->f[urm]==0)r=r->fail;
        if(r->f[urm]!=0)r=r->f[urm];
        ++r->n;
        i++;
    }
    antibfs();
    for(int i=1;i<=n;i++)printf("%d\n",w[i]);
   // parc(t,0);
}