Cod sursa(job #194312)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 9 iunie 2008 18:48:48
Problema Substr Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct keys {
	int x, y, p;

	keys (int _x = 0, int _y = 0, int _p = 0) :
	x(_x), y(_y), p(_p) {}

	bool operator==(keys b) {
		return x == b.x && y == b.y;
	}
};

const int LGMAX = 14;
const int NMAX = (1 << LGMAX) + 1;

int N, K, L;
char S[NMAX];
int A[LGMAX][NMAX], V[NMAX];
keys T[NMAX], C[NMAX];

void read(void) {
	FILE *fin = fopen("substr.in", "rt");

	fscanf(fin, " %d %d", &N, &K);

	fscanf(fin, " %s", S);

	fclose(fin);
}

void rsort(keys T[], int t) {
	int i;

	memset(V, 0x00, sizeof(V));

	for (i = 0; i < N; ++i)
		++V[ t ? T[i].y : T[i].x ];
	
	for (i = 1; i <= N; ++i)
		V[i] += V[i - 1];
	
	for (i = N-1; i >= 0; --i)
		C[ -- V[ t ? T[i].y : T[i].x ] ] = T[i];

	memcpy(T, C, sizeof(C));
}

void build(void) {
	int i, is, stp;

	for (i = 0; i < N; ++i)
		V[S[i] - 'a'] = 1;
	for (i = 1; i < 256; ++i)
		V[i] += V[i-1];
	for (i = 0; i < N; ++i)
		A[0][i] = V[ S[i] - 'a' ];

	for (stp = 1, is = 1; (stp << 1) < N; stp <<= 1, ++is) {
		
		for (i = 0; i < N; ++i)
			T[i] = keys(A[is-1][i], (i + stp < N ? A[is-1][i+stp] : 0), i);
/*
		for (i = 0; i < N; ++i)
			printf("(%d,%d) ", T[i].x, T[i].y);
		printf("\n");
*/
		rsort(T, 1);
		rsort(T, 0);
/*
		for (i = 0; i < N; ++i)
			printf("(%d,%d) ", T[i].x, T[i].y);
		printf("\n");
*/
		A[is][ T[0].p ] = 1;
		for (i = 1; i < N; ++i)
			A[is][ T[i].p ] = (T[i] == T[i-1] ? A[is][ T[i-1].p ] : i + 1);
	}
	L = is - 1;
/*
	for (is = 0; is <= L; ++is) {
		for (i = 0; i < N; ++i)
			printf("%2d ", A[is][i]);
		printf("\n");
	}
*/
}

int lcp(int x, int y) {
	if (x == y) return N - x;
	int k, ret = 0;

	for (k = L; k >= 0; --k)
		if (A[k][x] == A[k][y])
			ret += 1 << k, x += 1 << k, y += 1 << k;

	return ret;
}

void write(void) {
	FILE *fout = fopen("substr.out", "wt");
	int i, R = 0;

	for (i = 0; i <= N - K; ++i)
		R = max(R, lcp(T[i].p, T[i + K - 1].p));

	fprintf(fout, "%d\n", R);

	fclose(fout);
}

int main(void) {

	read();

	build();

	write();

	return 0;
}