Cod sursa(job #143086)

Utilizator raula_sanChis Raoul raula_san Data 25 februarie 2008 22:02:57
Problema Substr Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <cstdio>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

#define dim 16384 + 1
#define log 16

#define pb push_back
#define mp make_pair

using namespace std;

string S;
vector < pair < pair <int, int> , int > > V;
vector <int> Pos[dim];

int N;
int K;
int Sol;

int P[log][dim];

int LowestCommonPrefix(int, int);

void BuildArray()
{
	int i;
	for(i=0; i<N; ++i) P[0][i] = (int) S[i];

	int step;
	for(step=1; (1<<step)<=N; ++step)
	{
		V.clear();
		for(i=0; i<N; ++i)
		{
			int c0, c1;

			c0 = P[step-1][i];
			c1 = i + (1 << (step - 1)) < N ? P[step-1][i + (1 << (step - 1))] : -1;

			V.pb(mp(mp(c0, c1), i));
		}

		sort(V.begin(), V.end());

		for(i=0; i<N; ++i)
		{
			int j = V[i].second;

			if(i > 0 && V[i-1].first.first == V[i].first.first && V[i-1].first.second == V[i].first.second)
				P[step][j] = P[step][V[i-1].second];
			else
				P[step][j] = i;
		}
	}
}

void FindSolution()
{
	int i, j, k, lcp, step, max = 0;

	for(step=1; (1<<step)<=N; ++step);
	-- step;

	for(i=0; i<N; ++i)
	{
		Pos[P[step][i]].pb(i);
		max = P[step][i] > max ? P[step][i] : max;
	}

	k = K;
	K = K - 1 < max ? K - 1 : max;

	for(i=K; i<N; ++i)
	{
		j = i - k + 1;
		j = j < 0 ? 0 : j;

		vector <int> :: iterator it1, it2;

		for(it1=Pos[i].begin(); it1!=Pos[i].end(); ++it1)
			for(it2=Pos[j].begin(); it2!=Pos[j].end(); ++it2)
			{
				lcp = LowestCommonPrefix(*it1, *it2);
				Sol = lcp > Sol ? lcp : Sol;
			}
	}
}

int LowestCommonPrefix(int x, int y)
{
	int ret = 0, step;
	
	for(step=1; (1<<step)<=N; ++step);
	-- step;
	while(step >= 0)
	{
		if(P[step][x] == P[step][y])
			x += (1 << step), y += (1 << step), ret += (1 << step);
		-- step;
	}

	return ret;
}

int main()
{
	freopen("substr.in", "rt", stdin);
	freopen("substr.out", "wt", stdout);

	scanf("%d %d\n", &N, &K);
	cin >> S;

	BuildArray();
	FindSolution();

	printf("%d\n", Sol);

	fclose(stdin);
	fclose(stdout);
	return 0;
}