Cod sursa(job #189958)

Utilizator vladcyb1Vlad Berteanu vladcyb1 Data 19 mai 2008 14:37:58
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#define FIN "substr.in"
#define FOUT "substr.out"
#define MAX( a, b ) (a) > (b) ? (a) : (b)
#define MIN( a, b ) (a) < (b) ? (a) : (b)
#define NMAX 16385
#define LOGMAX 15

typedef struct nod
{
	int first, last;
} NOD;

char S[NMAX];
int SIGMA[255], SUFF[LOGMAX][NMAX], CNT[NMAX], IND[NMAX], TMP[NMAX], ORDER[NMAX] ;

NOD V[NMAX];
int N, K, max_step;

void Norm()
{
	int i;
	memset( SIGMA, 0, sizeof(SIGMA));
	for( i = 0; i < N; i++ )
		SIGMA[S[i]] = 1;
	for( i = 1; i < 255; i++ ) 
		SIGMA[i] = SIGMA[i-1] + SIGMA[i];
}

void count_sort()
{
    int i;
	memset( CNT, 0, sizeof(CNT) );
	for( i = 1; i <= N; i++ )
		CNT[V[i].last]++;
	for( i = 1; i <= N; i++ )
		CNT[i] += CNT[i-1];
	for( i = 1; i <= N; i++ )
	{
		TMP[CNT[V[i].last]] = i;
		CNT[V[i].last]--;
	}
	memset( CNT, 0, sizeof(CNT));
	for( i = 1; i <= N; i++ )
		CNT[V[i].first]++;
	for( i = 1; i <= N; i++)
		CNT[i] += CNT[i-1];
	for( i = N; i > 0; i-- )
	{
		IND[CNT[V[TMP[i]].first]] = TMP[i];
		CNT[V[TMP[i]].first]--;
		
	}
}

void build_suffix()
{
	int i, step, nr;
	 // initializez primul nivel
	for( i = 1; i <= N; i++ )
		SUFF[0][i] = SIGMA[S[i-1]];
    bool ord = false;
    step = 0;
    while( !ord )
    {
       	for( i = 1; i <= N; i++ )
    	{
    		V[i].first = SUFF[step][i];
    		if( i + ( 1 << step ) <= N )
    			V[i].last = SUFF[step][i + ( 1 << step )];
    		else
    			V[i].last = 0;
    	}
    		
    		count_sort();
    		nr = 1; step++;
    		SUFF[step][IND[1]] = nr;
    		
    		
    		for( i = 2; i <= N; i++ )
    		{
    			if( V[IND[i]].first != V[IND[i-1]].first || V[IND[i]].last != V[IND[i-1]].last )
    				nr++;
    		    SUFF[step][IND[i]] = nr;
    		}
    		
    		if( nr == N ) ord = true;	
    		
    			                     
    	}
    max_step = step;
    for( i = 1; i <= N; i++ ) 
    	ORDER[SUFF[step][i] ] = i;
      	
}

int lcp( int i, int j )
{
	int k = 0, step = max_step;
	if( i == j ) return N - i + 1;
	while( i <= N && j <= N && step >= 0 )
	{
		if( SUFF[step][i] == SUFF[step][j] )
		{
			k += 1 << step;
			i += 1 << step;
			j += 1 << step;
		}
		step--;
	}
	return k;
}



int solve()
{
	int max = 0, i;
	for( i = K; i <= N; i++ )
		max = MAX( max, lcp( ORDER[i - K + 1], ORDER[i] ));
	return max;
 
}

int main()
{
	FILE * fin = fopen( FIN, "r" );
	FILE * fout = fopen( FOUT, "w" );
	fscanf( fin, "%d%d\n", &N, &K );
	
	fscanf( fin, "%s", S );
	Norm();
	build_suffix();
	solve();
	fprintf( fout, "%d\n", solve() );
	fclose( fin );
	fclose( fout );
		
}