Cod sursa(job #545135)

Utilizator ooctavTuchila Octavian ooctav Data 2 martie 2011 19:22:33
Problema Substr Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<deque>
#include<queue>
#include<set>
#include<vector>
using namespace std;

const char IN[] = {"substr.in"};
const char OUT[] = {"substr.out"};
const int INF = 1000000005;
const double PI  = 3.14159265;
const int NMAX = 17000;
const int lgNMAX = 20;

#define II inline
#define LL long long
#define PII pair<int, int>
#define PDD pair<double, double>
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define FOR(i, a, b) 	for(int i = a ; i <= b ; i++)
#define IFOR(i, a, b) 	for(int i = a ; i >= b ; i--)
#define FORIT(it, V) 	for(vector<int> :: iterator it = V.begin() ; it != V.end() ; it++)
#define all(a) a, a + 

int N, K, lung;
int s[lgNMAX][NMAX];
char c[NMAX];
struct entry
{
	int nr[2], ind;
}L[NMAX];
int inv[NMAX];
int Lcp[NMAX];

void citi()
{
	scanf("%d%d\n", &N, &K);
	gets(c + 1);
}

bool cmp(entry x, entry y)
{
	return x.nr[0] != y.nr[0] ? x.nr[0] < y.nr[0] : x.nr[1] < y.nr[1];
}

void prefix()
{
	int k;
	FOR(i, 1, N)	s[0][i] = c[i] - 'a';
	for(lung = 1, k = 1 ; k <= N ; k <<= 1, lung++)
	{
		FOR(i, 1, N)
		{
			L[i].nr[0] = s[lung - 1][i];
			if(i + k <= N)	L[i].nr[1] = s[lung - 1][i + k];
			else			L[i].nr[1] = -1;
			L[i].ind = i;
		}
		sort(L + 1, L + N + 1, cmp);
		FOR(i, 1, N)
		{
			if(L[i].nr[0] == L[i - 1].nr[0] && L[i].nr[1] == L[i - 1].nr[1])
				s[lung][L[i].ind] = s[lung][L[i - 1].ind];
			else
				s[lung][L[i].ind] = i;
		}
	}
	lung--;
	FOR(i, 1, N)	inv[s[lung][i]] = i;
}

int lcp(int x, int y)
{
	int rez = 0;
	for(int step = lung ; step >= 0 && x <= N && y <= N ; step--)
		if(s[step][x] == s[step][y])
			x += (1<<step), y += (1<<step), rez += (1<<step);
	return rez;
}

void numara()
{
	FOR(i, 2, N)
		Lcp[i] = lcp(inv[i], inv[i - 1]);
}

bool ok(int x)
{
	int nr = 0;
	FOR(i, 2, N)
	{
		if(Lcp[i] >= x)
		{
			if(nr == 0)	nr++;
			nr++;
		}
		else	nr = 0;
		
		if(nr >= K)	return 1;
	}
	return 0;
}

int caut_bin()
{
	int REZ = 0, step;
	for(step = 1 ; step <= N ; step <<= 1);
	for(; step ; step >>= 1)
		if(REZ + step <= N)
			if(ok(REZ + step))
				REZ += step;
	return REZ;
}

int main()
{
	freopen(IN, "r", stdin);
	freopen(OUT, "w", stdout);
	citi();
	prefix();
	numara();
	printf("%d\n", caut_bin());
	return 0;
}