Cod sursa(job #104419)

Utilizator octavOctavian Voicu octav Data 16 noiembrie 2007 05:11:51
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Happy Coding 2007 Marime 1.48 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];
char text[MAXTEXT + 1];

// Aho-Corasick set matching
int solve(int n) {
	char *p;
	int i, j, k, t, ql, qr, ch, count;

	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++) {
			t = next[i][j];
			if(!t) continue;
			queue[qr++] = t;
			k = f[i];
			while(!next[k][j]) k = f[k];
			k = next[k][j];
			f[t] = k;
			q[t] += q[k];
		}
	}

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

	return count;
}

int main() {
	int nodes, i, n, t, ch;

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

	for(n = 0; (ch = fgetc(stdin)) != EOF && ch != '\n'; ) {
		if(ch < 'a' || ch > 'c') continue;
		text[++n] = ch - 'a';
	}

	nodes = 1;
	while(1) {
		t = 1;
		for(i = 0; (ch = fgetc(stdin)) != EOF && ch != '\n'; ) {
			if(ch < 'a' || ch > 'c') continue;
			i++;
			ch -= 'a';
			if(!next[t][ch]) next[t][ch] = ++nodes;
			t = next[t][ch];
		}
		if(!i) break;
		q[t] = 1;
	}

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

	return 0;
}