Cod sursa(job #1141633)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 13 martie 2014 00:00:49
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.87 kb
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int NMAX = 1000005;
const int MMAX = 10005;
int N,M,C,i,j,L,R,Letter,Sol[MMAX];
char A[NMAX],B[MMAX];
struct Trie
{
    vector<int> V;
    Trie *Son[26];
    Trie *Fail;
    int Count;
    Trie()
    {
        memset(Son,0,sizeof(Son));
        Fail=NULL; Count=0;
    }
};
Trie *Root=new Trie;
Trie *Q[MMAX*MMAX],*X,*Y,*F;
void Insert(Trie *T,int Poz)
{
    if(Poz==M) {T->V.push_back(i); return;}
    Letter=B[Poz]-'a';
    if(!T->Son[Letter]) T->Son[Letter]=new Trie;
    Insert(T->Son[Letter],Poz+1);
}
void Read()
{
    freopen("ahocorasick.in","r",stdin);
	freopen("ahocorasick.out","w",stdout);

	scanf("%s",A+1);
	N=strlen(A+1);

	scanf("%d",&C);
	for(i=1;i<=C;i++)
	{
	    scanf("%s",B);
	    M=strlen(B);
	    Insert(Root,0);
	}
}
void BFS()
{
    Root->Fail=Root; L=R=1; Q[1]=Root;
    while(L<=R)
    {
        X=Q[L++];
        for(j=0;j<26;j++)
            if(X->Son[j]!=NULL)
            {
                Y=X->Son[j];
                for(F=X->Fail;F!=Root && F->Son[j]==NULL;F=F->Fail);
                if(F->Son[j]!=NULL && F->Son[j]!=Y) F=F->Son[j];
                Y->Fail=F;
                Q[++R]=Y;
            }
    }
}
void AhoCorasick()
{
    Root->Fail=NULL; X=Root;
    for(i=1;i<=N;i++)
    {
        Letter=A[i]-'a';
        while(X->Son[Letter]==NULL && X!=Root) X=X->Fail;
        if(X->Son[Letter]!=NULL) X=X->Son[Letter];
        X->Count++;
    }
}
void AntiBFS()
{
    for(i=R;i;i--)
    {
        X=Q[i];
        if(X->Fail!=NULL) X->Fail->Count+=X->Count;
        for(vector<int>::iterator it=X->V.begin();it!=X->V.end();it++)
            Sol[*it]+=X->Count;
    }
}
void Print()
{
    for(i=1;i<=C;i++) printf("%d\n",Sol[i]);
}
int main()
{
	Read();
	BFS();
	AhoCorasick();
	AntiBFS();
	Print();
	return 0;
}