Cod sursa(job #543694)

Utilizator mottyMatei-Dan Epure motty Data 28 februarie 2011 15:04:24
Problema Substr Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.6 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 16385, logN = 14;

int n, k;
char str[N];
int lcp[logN][N];
int pow;

vector < pair<int,int> > suf;

void Read()
{
	scanf("%d%d\n",&n,&k);
	gets(str+1);
}

int ciompear(pair <int,int> a, pair <int,int> b)
{
	if(lcp[pow-1][a.first] == lcp[pow-1][b.first])
		return lcp[pow-1][a.first + (1<<(pow - 1))] < lcp[pow-1][b.first + (1<<(pow - 1))];
	
	return lcp[pow-1][a.first] < lcp[pow-1][b.first];
}

void GetSecond()
{
	int count = 0;
	for (int i=0; i<n; ++i)
		if(lcp[pow-1][suf[i].first] == lcp[pow-1][suf[i-1].first])
		{
			if(lcp[pow-1][suf[i].first + (1<<(pow - 1))] != lcp[pow-1][suf[i-1].first + (1<<(pow - 1))])
				count++;
			
			lcp[pow][suf[i].first] = count;
		}
		else
		{
			lcp[pow][suf[i].first] = ++count;
		}
}

void GetLCP()
{
	for (int i = 1; i <= n; ++i)
		lcp[0][i] = str[i] - 'a';
	
	for (pow=1; (1<<pow) < n; ++pow)
	{
		for (int i=1; i<=n; ++i)
			suf.push_back( make_pair(i, 0) );
		
		sort(suf.begin(), suf.end(), ciompear);
		
		GetSecond();
	}
	
	--pow;
}

int LCP(int i, int j, int pAct)
{
	if(pAct == -1)
		return 0;
	
	if(lcp[pAct][i] == lcp[pAct][j])
		return (1<<pAct) + LCP(i+pAct, j+pAct, pAct-1);
	
	return LCP(i, j, pAct-1);
}

void GetAnswer()
{
	int result = 0, rAct;
	
	for( int i=1; i<=n; ++i)
	{
		rAct = LCP(i, i+k, pow);
		
		if(rAct > result)
			result = rAct;
	}
}

int main()
{
	freopen("substr.in", "r", stdin);
	freopen("substr.out", "w", stdout);

	Read();
	GetLCP();
	GetAnswer();
	
	return 0;
}