Cod sursa(job #167588)

Utilizator vlad.maneaVlad Manea vlad.manea Data 29 martie 2008 20:21:01
Problema Substr Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.92 kb
#include <stdio.h>
#define nmax 16384
#define base 62
#define primmax 2000005

int N, K, ans;

char S[nmax];

int T[nmax], W[3][primmax], E[3][primmax], C[3][primmax], base2[3][nmax];

int mod[] = {1000003, 2000003, 1000033};

int minim(int l, int r)
{
	return l < r ? l : r;
}

void read()
{
	freopen("substr.in", "r", stdin);
	scanf("%d%d\n", &N, &K);
	scanf("%s", &S);
}

void normalize()
{
	int i, k;

	for (i = 0; i < N; ++i)
	{
		if ('a' <= S[i] && S[i] <= 'z')
			T[i] = S[i]-'a';
		else if ('A'<=S[i] && S[i] <= 'Z')
			T[i] = S[i]-'A'+26;
		else
			T[i] = S[i]-'0'+52;
	}

	for (base2[0][0] = base2[1][0] = base2[2][0] = i = 1; i <= N; ++i)
		for (k = 0; k < 3; ++k)
			base2[k][i] = base * base2[k][i-1] % mod[k];
}

void bs(int l, int r)
{
	int i, k, mini, min;

	if (l > r)
		return;

	int L = (l+r)>>1;

	for (i = W[0][L-1] = W[1][L-1] = W[2][L-1] = 0; i < L; ++i)
		for (k = 0; k < 3; ++k)
			W[k][L-1] = (W[k][L-1] % mod[k] * base + T[i]) % mod[k];

	for (k = 0; k < 3; ++k)
		if (E[k][W[k][L-1]] != L)
		{
			C[k][W[k][L-1]] = 1;
			E[k][W[k][L-1]] = L;
		}
		else
			++C[k][W[k][L-1]];

	mini = minim(C[0][W[0][L-1]], C[1][W[1][L-1]]);
	mini = minim(mini, C[2][W[2][L-1]]);

	for (i = L; i < N; ++i)
	{
		for (k = 0; k < 3; ++k)
		{
			W[k][i] = (mod[k] + W[k][i-1] * base % mod[k] + T[i] % mod[k] - T[i-L] * base2[k][L] % mod[k]) % mod[k];
			if (E[k][W[k][i]] != L)
			{
				C[k][W[k][i]] = 1;
				E[k][W[k][i]] = L;
			}
			else
				++C[k][W[k][i]];

		}

		min = minim(C[0][W[0][i]], C[1][W[1][i]]);
		min = minim(min, C[2][W[2][i]]);

		if (min > mini)
			mini = min;
	}

	if (mini >= K)
	{
		ans = L;
		bs(L+1, r);
	}
	else
		bs(l, L-1);
}

void solve()
{
	normalize();

	bs(1, N);
}

void write()
{
	freopen("substr.out", "w", stdout);
	printf("%d\n", ans);
}

int main()
{
	read();

	solve();

	write();

	return 0;
}