Cod sursa(job #2288870)

Utilizator mateibanuBanu Matei Costin mateibanu Data 24 noiembrie 2018 01:38:37
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.91 kb
#include <bits/stdc++.h>

using namespace std;

#define LA (int)(2+1e6)
#define LS (int)(2+1e4)

char a[LA],s[LS];
int n,m,p[101],r[101],k;

struct nod{
    int k,val;
    nod *urm[26],*ant;
    nod() {
        k=0;
        val=0;
        ant=0;
        memset(urm,0,sizeof(urm));
    }
};
nod *o = new nod;
nod *aux;
deque<nod*>q,q2;

void add(){
    int i;
    nod *x=o;
    for (i=0;i<n;i++){
        if (x->urm[s[i]-'a']==0){
            x->urm[s[i]-'a']= new nod;
        }
        x=x->urm[s[i]-'a'];
    }
    if (x->k==0) x->k=k;
    p[k]=x->k;
}

void bf(){
    int i;
    nod* bk;
    nod* x;
    for (i=0;i<26;i++)
    if (o->urm[i]!=0){
        o->urm[i]->ant=o;
        q2.push_back(o->urm[i]);
    }
    while (!q2.empty()){
        x=q2.front();
        q.push_back(x);
        q2.pop_front();
        for (i=0;i<26;i++)
            if (x->urm[i]!=0){
                bk=x->ant;
                while (bk!=o&&bk->urm[i]==0)
                    bk=bk->ant;
                if (bk->urm[i]!=0) x->urm[i]->ant=bk->urm[i];
                else	x->urm[i]->ant=o;
                q2.push_back(x->urm[i]);
            }
    }
}

void potrivire(){
    nod *x=o;
    int i;
    for (i=0;i<m;i++){
		while (x!=o&&x->urm[a[i]-'a']==0)
			x=x->ant;
		if(x->urm[a[i]-'a']!=0)	x=x->urm[a[i]-'a'];
		x->val++;
    }
}

void solve(){
    nod *x;
    while (!q.empty()){
        x=q.back();
        x->ant->val+=x->val;
        if (r[x->k]==0) r[x->k]=x->val;
        q.pop_back();
    }
}

int main()
{
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
    int nr,i;
    scanf("%s%d",a,&nr);
    m=strlen(a);
    for (k=1;k<=nr;k++){
        scanf("%s",s);
        n=strlen(s);
        add();
    }
    o->ant=o;
    bf();
    potrivire();
    solve();
    for (i=1;i<=nr;i++)
        printf("%d\n",r[p[i]]);
    return 0;
}