Cod sursa(job #194331)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 9 iunie 2008 21:19:59
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 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, t;

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

	t = V[255];
	for (stp = 1, is = 1; stp < N && t != 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 ] = t = 1;
		for (i = 1; i < N; ++i)
			A[is][ T[i].p ] = t += !(T[i] == T[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 (x + (1 << k) < N && y + (1 << k) < N && A[k][x] == A[k][y])
		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;
}