Cod sursa(job #2281)

Utilizator MariusMarius Stroe Marius Data 16 decembrie 2006 18:59:54
Problema Substr Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <cstdio>
#include <algorithm>
using namespace std;

const char iname[] = "substr.in";
const char oname[] = "substr.out";

#define MAX_N  16385
#define MAX_LG 16

char A[MAX_N];

struct entry {
	int nr[2];
	int p;
} L[MAX_N];

int P[MAX_LG][MAX_N], N, K;

int Q[MAX_N], index[MAX_N];

int X[MAX_N];


int lca(const int stp, int x, int y)
{
	int k;
	int len = 0;

	if (x == y)
		return N - x;
	for (k = stp; 0 <= k && x < N && y < N; --k)
		if (P[k][x] == P[k][y]) {
			x += 1 << k;
			y += 1 << k;
			len += 1 << k;
		}
	return len;
}

int cmp(entry a, entry b) {
	return a.nr[0] == b.nr[0] ? (a.nr[1] < b.nr[1] ? 1 : 0) :
								(a.nr[0] < b.nr[0] ? 1 : 0);
}

int main(void)
{
	freopen(iname, "r", stdin);
	freopen(oname, "w", stdout);
	int i;
	int stp;
	int cnt;
	int len;
	int head, tail;

	int RES = 0;

	scanf("%d %d\n", & N, & K);
	scanf("%s", A);
	for (i = 0; i < N; ++i) {
		if ('0' <= A[i] && A[i] <= '9')
			P[0][i] = A[i] - '0';
		else if ('A' <= A[i] && A[i] <= 'Z')
			P[0][i] = A[i] - 'A' + 10;
		else
			P[0][i] = A[i] - 'a' + 10 + 26;
	}
	for (cnt = stp = 1; cnt >> 1 < N; cnt <<= 1, ++stp) {
		for (i = 0; i < N; ++i) {
			L[i].nr[0] = P[stp - 1][i];
			L[i].nr[1] = i + cnt < N ? P[stp - 1][i + cnt] : -1;
			L[i].p = i;
		}
		sort(L, L + N, cmp);
		for (i = 0; i < N; ++i)
			P[stp][L[i].p] = i > 0 && L[i].nr[0] == L[i - 1].nr[0] &&
							 L[i].nr[1] == L[i - 1].nr[1] ? P[stp][L[i - 1].p] : i;
	}
	for (i = 0; i < N; ++i)
		X[P[stp - 1][i]] = i;
	
	head = tail = 0;
	for (i = 1; i < N; ++i) {
		len = lca(stp - 1, X[i - 1], X[i]);
		for (; head < tail && index[head] <= i - K + 1; ++head)
			;
		for (; head < tail && len <= Q[tail - 1]; --tail)
			;
		index[tail] = i;
		Q[tail] = len;
		tail += 1;
		if (K <= i - 1)
			if (RES < Q[head])	RES = Q[head];
	}
	if (K == 1)
		RES = N;
	printf("%d\n", RES);

	return 0;
}