Mai intai trebuie sa te autentifici.

Cod sursa(job #1153766)

Utilizator andreiiiiPopa Andrei andreiiii Data 25 martie 2014 18:31:48
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

struct ac{
    vector <int> words;
    int n0;
    ac *f[26], *fail;
    ac()
    {
        n0=0;
        fail=0;
        memset(f, 0, sizeof(f));
    }
};

ac *Q[100003], *T=new ac;
char a[1000005], word[10005];
int sol[105], Qst, Qdr;

void ac_insert(ac *T, char *s, int i)
{
    if(*s=='\n')
    {
        T->words.push_back(i);
        return;
    }
    if(!T->f[*s-'a']) T->f[*s-'a']=new ac;
    ac_insert(T->f[*s-'a'], s+1, i);
}

void ac_bfs(ac *T)
{
    ac *p, *k;
    int i;
    T->fail=T;
    for(Q[Qst=Qdr=1]=T;Qst<=Qdr;Qst++)
    {
        p=Q[Qst];
        for(i=0;i<26;i++)
        {
            if(!p->f[i]) continue;
            for(k=p->fail;k!=T&&!k->f[i];k=k->fail);
            if(k->f[i]&&k!=p) k=k->f[i];
            p->f[i]->fail=k;
            Q[++Qdr]=p->f[i];
        }
    }
    T->fail=0;
}

void ac_antibfs(ac *T)
{
    int i;
    ac *p;
    for(i=Qdr;i;i--)
    {
        p=Q[i];
        if(p->fail) p->fail->n0+=p->n0;
        for(auto x: p->words) sol[x]=p->n0;
    }
}

int main()
{
    freopen("ahocorasick.in", "r", stdin);
    freopen("ahocorasick.out", "w", stdout);
    int n, m, i, x;
    fgets(a, 1000005, stdin); m=strlen(a)-1;
    scanf("%d\n", &n);
    for(i=1;i<=n;i++)
    {
        fgets(word, 10005, stdin);
        ac_insert(T, word, i);
    }
    ac_bfs(T);
    ac *p=T;
    for(i=0;i<m;i++)
    {
        x=a[i]-'a';
        for(;!p->f[x]&&p!=T;p=p->fail);
        if(p->f[x]) p=p->f[x];
        p->n0++;
    }
    ac_antibfs(T);
    for(i=1;i<=n;i++) printf("%d\n", sol[i]);
}