Cod sursa(job #184600)

Utilizator anoukAnca Dumitrache anouk Data 23 aprilie 2008 22:09:55
Problema Substr Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.53 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>

#define DIM 17000
#define LG 15

using namespace std;

int N, K, P[DIM][LG], stp;
char S[DIM];
struct entry {
	int nr[2], p;
};
entry L[LG];

struct cmp {
	bool operator () (entry A, entry B)
	{
		if (A.nr[0] < B.nr[0]) return true;
		if (A.nr[0] == B.nr[0] && A.nr[1] < B.nr[1]) return true;
		return false;
	}
};

int lcp(int X, int Y)
{
	if (X == Y) return N - X;
	int sol = 0;
	for (int i = stp - 1; i >= 0 && X < N && Y < N; i--)
		if (P[X][i] == P[Y][i])
		{
			X += 1 << i;
			Y += 1 << i;
			sol += 1 << i;
		}
	return sol;
}

int main()
{
	FILE *fin = fopen("substr.in", "r");
	FILE *fout = fopen("substr.out", "w");

	char ch;
	fscanf(fin, "%d%d%c", &N, &K, &ch);
	fscanf(fin, "%s", S);

	int i, j, x, sol = 0;
	for (i = 0; i < N; i++)
		if (S[i] >= '0' && S[i] <= '9')      P[i][0] = S[i] - '0';
		else if (S[i] >= 'A' && S[i] <= 'Z') P[i][0] = S[i] - 'A' + 10;
		else                                 P[i][0] = S[i] - 'a' + 36;
	for (j = 1; (1 << j) < N; j++)
	{
		for (i = 0; i < N; i++)
		{
			x = i + (1 << (j - 1));
			L[i].nr[0] = P[i][j - 1];
			L[i].nr[1] = x < N ? P[x][j - 1] : -1;
			L[i].p = i;
		}
		sort(L, L + N, cmp());
		for (i = 0; i < N; i++)
			if (i && L[i].nr[0] == L[i - 1].nr[0] && L[i].nr[1] == L[i - 1].nr[1])
				P[L[i].p][j] = P[L[i - 1].p][j];
			else
				P[L[i].p][j] = i;
	}

	stp = j;
	for (i = 0; i <= N - K; i++)
	{
		x = lcp(L[i].p, L[i + K - 1].p);
		sol = max(sol, x);
	}
	fprintf(fout, "%d\n", sol);

	fclose(fin);
	fclose(fout);
	return 0;
}