Cod sursa(job #2286)

Utilizator MariusMarius Stroe Marius Data 16 decembrie 2006 19:06:03
Problema Substr Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 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], T[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;
}

void sort(entry L[], const int N, const int ind)
{
	int i;

	memset(X, 0, sizeof(X));
	for (i = 0; i < N; ++i)
		X[L[i].nr[ind] + 1] += 1;
	for (i = 1; i < MAX_N; ++i)
		X[i] += X[i - 1];
	for (i = N; i--; )
		T[--X[L[i].nr[ind] + 1]] = L[i];
	for (i = N; i--; )
		L[i] = T[i];
}

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, N, 1);
		sort(L, N, 0);
		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 - 1 <= i)
			if (RES < Q[head])	RES = Q[head];
	}
	if (K == 1)
		RES = N;
	printf("%d\n", RES);

	return 0;
}