Cod sursa(job #846682)

Utilizator test_13testing test_13 Data 2 ianuarie 2013 17:04:35
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstring>
#include <vector>
#include <deque>
#include <queue>
#include <set>
using namespace std;
#define inf 0xffffff
#define Max 1000001

char a[Max];
char b[10001];
int n,num[101],u;
struct dic{ 
	int nr; 
	vector<int>cuv;
	struct dic *f[26];
	struct dic *fail;
	dic(){ for(int i=0;i<26;i++)f[i]=NULL; nr=0; cuv.resize(0); } }*t,*c[Max];

void insert(int idx,char *b)
{
	dic *g=t;
	int urm;
	while( isalpha(*b) )
	{
		urm=*b-'a';
		if(g->f[urm]==NULL)g->f[urm]=new dic;
		g=g->f[urm];
		b++;
	}
	g->cuv.push_back(idx);
}

void bfs()
{
	dic *fr,*dir;
	int p;
		t->fail=t;
		c[p=u=1]=t;
	while(p<=u)
	{
		fr=c[p++];
		for(int i=0;i<26;i++)
			if(fr->f[i]!=NULL)
			{
				for(dir=fr->fail;dir!=t && dir->f[i]==NULL;dir=dir->fail);
				if(dir->f[i]!=NULL && fr->f[i] != dir->f[i])dir=dir->f[i];
				fr->f[i]->fail=dir;
				c[++u]=fr->f[i];
			}
	}
	t->fail=NULL;
}

void ahocorasick(char *b)
{
	dic *g=t;
	int urm;
	while( isalpha(*b) )
	{
		urm=*b-'a';
		while(g!=t && g->f[urm]==NULL)g=g->fail;
		if(g->f[urm]!=NULL)g=g->f[urm];
		g->nr++;
		b++;
	}
}

void antibfs()
{
	dic *fr;
	while(u>0)
	{
		fr=c[u--];
		if(fr->fail!=NULL)fr->fail->nr+=fr->nr;
		for(int i=0;i<fr->cuv.size();i++)num[fr->cuv[i]]=fr->nr;
	}
}

int main()
{
	freopen("ahocorasick.in","r",stdin);
	freopen("ahocorasick.out","w",stdout);
		scanf("%s ",a);
		scanf("%d ",&n);
		t = new dic;
		for(int i=1;i<=n;i++)
		{
			scanf("%s ",b);
			insert(i,b);
		}
		bfs();
		ahocorasick(a);
		antibfs();
		for(int i=1;i<=n;i++)printf("%d\n",num[i]);
	return 0;
}