Cod sursa(job #104439)

Utilizator octavOctavian Voicu octav Data 16 noiembrie 2007 06:05:40
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Happy Coding 2007 Marime 1.41 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXTEXT 10000000
#define MAXLEN 20
#define MAXWORDS 50000
#define MAXNODES (MAXWORDS * MAXLEN + 1)
#define CHARSET 3

int next[MAXNODES][CHARSET], f[MAXNODES], q[MAXNODES], queue[MAXNODES], nodes;
char text[MAXTEXT + 1];

void trie_add(char *word) {
	char *p;
	int t, ch;

	for(p = word, t = 1; *p; p++) {
		ch = *p - 'a';
		if(!next[t][ch]) next[t][ch] = ++nodes;
		t = next[t][ch];
	}
	q[t] = 1;
}

void build_failure() {
	int i, j, k, a, ql, qr;

	ql = qr = 0;
	for(i = 0; i < CHARSET; i++) {
		if(next[1][i]) {
			f[next[1][i]] = 1;
			queue[qr++] = next[1][i];
		} else {
			next[1][i] = 1;
		}
	}

	while(ql < qr) {
		i = queue[ql++];
		for(j = 0; j < CHARSET; j++) {
			a = next[i][j];
			if(!a) continue;
			queue[qr++] = a;
			k = f[i];
			while(!next[k][j]) k = f[k];
			k = next[k][j];
			f[a] = k;
			q[a] += q[k];
		}
	}
}

// Aho-Corasick set matching
int solve() {
	char *p;
	int t, ch, count;

	count = 0;
	t = 1;
	for(p = text; *p; p++) {
		ch = *p - 'a';
		while(!next[t][ch]) t = f[t];
		t = next[t][ch];
		count += q[t];
	}

	return count;
}

int main() {
	char word[MAXLEN + 1];

	freopen("abc2.in", "rt", stdin);
	freopen("abc2.out", "wt", stdout);

	gets(text);

	nodes = 1;
	while(gets(word)) trie_add(word);
	build_failure();

	printf("%d\n", solve());

	return 0;
}