Cod sursa(job #188252)

Utilizator scvalexAlexandru Scvortov scvalex Data 7 mai 2008 17:09:06
Problema Abc2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
#include <iostream>
#include <fstream>

using namespace std;

/*
 * Un trie,
 * Si un vector foarte mic,
 * Fac un automat finit.
 */

char s[10000001];
int L;
char w[50000][21];
int lw[50000], N;

int root;
int trie[1100000][3];
bool final[1100000];
int dfa[1100000][3];

void df_trie(int state, int ncand, int *cand)
{
	int nextstate;

	for (int i(0); i < 3; ++i)
		if (!dfa[state][i]) {
			nextstate = root;

			for (int j(0); j < ncand; ++j)
				if (trie[cand[j]][i] > 0) {
					nextstate = trie[cand[j]][i];
					break;
				}

			dfa[state][i] = nextstate;
		}

	int *newcand = new int[ncand+1];
	int newncand;

	for (int i(0); i < 3; ++i)
		if (trie[state][i] > 0) {
			newncand = 0;
			
			/* adauga toate starile in care se poate
			 * ajunge trecand printr-o muchie de tip i */
			for (int j(0); j < ncand; ++j)
				if (trie[cand[j]][i] > 0)
					newcand[newncand++] = trie[cand[j]][i];

			/* in radacina se poate ajunge prin orice fel
			 * de muchie */
			newcand[newncand++] = root;

			df_trie(trie[state][i], newncand, newcand);
		}

	delete newcand;
}

int main(int argc, char *argv[])
{
	FILE *fi = fopen("abc2.in", "r");
	fscanf(fi, "%s", s);
	L = strlen(s);
	for (N = 0; ; ++N) {
		fscanf(fi, "%s", w[N]);

		if (!w[N][0])
			break;

		lw[N] = strlen(w[N]);
	}
	fclose(fi);

	root = 1;
	int nstates = 1;

	int state;
	for (int cuv(0); cuv < N; ++cuv) {
		state = root;

		for (int i(0); i < lw[cuv]; ++i) {
			if (final[state])
				break;

			w[cuv][i] -= 'a';

			if (!trie[state][(int)w[cuv][i]]) {
				++nstates;
				dfa[state][(int)w[cuv][i]] = trie[state][(int)w[cuv][i]] = nstates;
			}

			state = trie[state][(int)w[cuv][i]];
		}

		final[state] = true;
	}

	df_trie(root, 0, 0);

	int R(0);
	state = root;

	for (int i(0); i < L; ++i) {
		s[i] -= 'a';

		state = dfa[state][(int)s[i]];
		if (final[state])
			++R;
	}

	ofstream fout("abc2.out");
	fout << R << endl;
	fout.close();

	return 0;
}