Cod sursa(job #180948)

Utilizator scvalexAlexandru Scvortov scvalex Data 17 aprilie 2008 18:15:57
Problema Substr Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <iostream>
#include <fstream>

using namespace std;

int N, K;
char A[16385];
int P[16][16385];

struct entry {
	int nr[2];
	int p;
} L[16385], T[16385];

int lca(int stp, int x, int y)
{
	if (x == y)
		return N - x;

	int len(0);
	for (int 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 X[16385];
void sort(entry L[], const int N, const int ind)
{
	memset(X, 0, sizeof(X));
	for (int i(0); i < N; ++i)
		++X[L[i].nr[ind]+1];
	for (int i(1); i < 16385; ++i)
		X[i] += X[i-1];
	for (int i = N; i > 0; --i)
		T[--X[L[i].nr[ind] + 1]] = L[i];
	for (int i = N; i > 0; --i)
		L[i] = T[i];
}

int Q[16385], ind[16385];
int main(int argc, char *argv[]) 
{
	FILE *fi = fopen("substr.in", "r");
	fscanf(fi, "%d %d", &N, &K);
	fscanf(fi, "%s", A);
	fclose(fi);

	for (int 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;
	}

	int cnt, stp;
	for (cnt = stp = 1; (cnt >> 1) < N; cnt <<= 1, ++stp) {
		for (int 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 (int 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 (int i(0); i < N; ++i)
		X[P[stp-1][i]] = i;

	int head(0),
	    tail(0);
	int r(0);
	for (int i(1); i < N; ++i) {
		int len = lca(stp-1, X[i-1], X[i]);
		for (; (head < tail) && (ind[head] <= i - K + 1); ++head)
			;
		for (; (head < tail) && (len <= Q[tail-1]); --tail)
			;
		ind[tail] = i;
		Q[tail] = len;
		tail += 1;
		if (K - 1 <= i)
			if (r < Q[head])
				r = Q[head];
	}
	if (K == 1)
		r = N;

	ofstream fout("substr.out");
	fout << r << endl;
	fout.close();

	return 0;
}