Cod sursa(job #143109)

Utilizator raula_sanChis Raoul raula_san Data 25 februarie 2008 22:29:55
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.95 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, lcp, step;

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

	for(i=0; i<N; ++i)
		Pos[P[step][i]].pb(i);

	for(i=K-1; 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;
	
	if(x == y) return N - x;

	for(step=1; (1<<step)<=N; ++step);
	-- step;
	while(step >= 0 && x < N && y < N)
	{
		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;
}