Cod sursa(job #1455583)

Utilizator darrenRares Buhai darren Data 28 iunie 2015 15:26:51
Problema Aho-Corasick Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include <cstring>
#include <fstream>
#include <algorithm>
#include <queue>

using namespace std;

struct Trie
{
	int val;
	Trie *nxt[26], *bck;
	
	Trie()
	{
		val = 0;
		memset(nxt, 0, sizeof(nxt));
		bck = 0;
	}
};

Trie *R = new Trie();

char A[1000002], B[10002];
Trie *wh[102];
queue<Trie*> Q;
int N;

void Add(Trie *T, char *now, int ind)
{
	if (*now == 0)
	{
		wh[ind] = T;
		return;
	}
	
	if (T->nxt[*now - 'a'] == 0)
		T->nxt[*now - 'a'] = new Trie();
		
	Add(T->nxt[*now - 'a'], now + 1, ind);
}

void Dfs(Trie* T)
{
	for (int i = 0; i < 26; ++i)
		if (T->nxt[i] != 0)
			Dfs(T->nxt[i]);
	if (T->bck != 0)
		T->bck->val += T->val;
}

int main()
{
	ifstream fin("ahocorasick.in");
	ofstream fout("ahocorasick.out");
	
	fin >> A >> N;
	for (int i = 1; i <= N; ++i)
	{
		fin >> B;
		Add(R, B, i);
	}
	
	Q.push(R);
	while (!Q.empty())
	{
		Trie *T = Q.front();
		Q.pop();
		
		for (int i = 0; i < 26; ++i)
			if (T->nxt[i] != 0)
			{
				Trie *now = T->bck;
				while (now != 0 && now->nxt[i] == 0)
					now = now->bck;
				
				if (now == 0) T->nxt[i]->bck = R;
				else          T->nxt[i]->bck = now->nxt[i];
				
				Q.push(T->nxt[i]);
			}
	}
	
	Trie *T = R;
	for (int i = 0; A[i] != 0; ++i)
	{
		while (T != 0 && T->nxt[A[i] - 'a'] == 0)
			T = T->bck;
		
		if (T == 0) T = R;
		else        T = T->nxt[A[i] - 'a'];

		++T->val;
	}
	
	Dfs(R);
	
	for (int i = 1; i <= N; ++i)
		fout << wh[i]->val << '\n';
	
	fin.close();
	fout.close();
}