Cod sursa(job #98156)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 10 noiembrie 2007 10:29:28
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Happy Coding 2007 Marime 1.97 kb
#include <cstdio>
#include <vector>
#include <string>

using namespace std;

#define MAXL 10000005
#define MAXN (50005*21)
#define SIGMA 3

int N;
char s[MAXL];
char tmp[32];

vector<string> v;
vector< vector<int> > stari;

int Tr[MAXN][SIGMA], niv[MAXN], p[MAXN], term[MAXN], DFA[MAXN][SIGMA], NR;

inline int add( string s, int ID )
{
	int i = 0, j, stare = 0;
	vector<int> st;
	for (; s[i]; i++)
	{
		if (Tr[stare][ s[i] - 'a' ] == -1)
		{
			Tr[stare][ s[i] - 'a' ] = ++NR;
			for (j = 0; j < SIGMA; j++)
				Tr[NR][j] = -1;
			niv[NR] = niv[stare] + 1;
			p[NR] = stare;
			stare = NR;
		}
		else
			stare = Tr[stare][ s[i] - 'a' ];
		st.push_back( stare );
	}
	stari.push_back(st);
	return stare;
}

int main()
{
	freopen("abc2.in", "rt", stdin);
	freopen("abc2.out", "wt", stdout);
	int i;
	fgets(s, MAXL, stdin);
	for (i = 0; 'a' <= s[i] && s[i] <= 'z'; i++);
	s[i] = 0;

	v.clear();
	stari.clear();
	for (N = 0; fgets(tmp, 32, stdin); )
	{
		N++;
		
		int k;
		for (k = 0; 'a' <= tmp[k] && tmp[k] <= 'z'; k++);
		tmp[k] = 0;

		if (k == 0) continue;
		v.push_back( tmp );
	}

	//init
	NR = 0; p[0] = -1;
	memset(term, 0, sizeof(term));
	for (i = 0; i < SIGMA; i++)
	{
		Tr[0][i] = -1;
		DFA[0][i] = 0;
	}

	//make trie
	for (i = 0; i < N; i++)
		term[ add( v[i], i ) ] = 1;

	//make DFA
	int is = 1;
	for (i = 0; is; i++)
	{
		int j;
		is = 0;
		for (j = 0; j < N; j++)
			if ((int)v[j].size() > i)
			{
				int k, stare, parent, aux, C = v[j][i] - 'a';
				is = 1;
				stare = stari[j][i];
				parent = p[stare];
				aux = DFA[ parent ][ C ];
				if (term[ DFA[parent][ C ] ])
					term[stare] = 1;

				DFA[parent][ C ] = stare;
				for (k = 0; k < SIGMA; k++)
					DFA[stare][k] = DFA[aux][k];
				if (niv[aux] == niv[parent])
					for (k = 0; k < SIGMA; k++)
						if (Tr[aux][k] != -1)
							DFA[stare][k] = Tr[aux][k];
			}
	}

	//get matchings
	int stare = 0, NR = 0;
	for (i = 0; s[i]; i++)
	{
		stare = DFA[stare][ s[i] - 'a' ];
		if (term[stare])
			NR++;
	}

	printf("%d\n", NR);
	return 0;
}