Cod sursa(job #81813)

Utilizator vladcoderVlad Ion vladcoder Data 4 septembrie 2007 17:47:19
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <stdio.h>
#include <string.h>
#define FIN "substr.in"
#define FOUT "substr.out"
#define NMAX 16400
#define LOGMAX 15
#define MIN( a, b ) ( (a) < (b) ) ? a : b

 struct data
{
	int first, last;
} V[NMAX];

int SUFF[LOGMAX][NMAX], RMQ[LOGMAX][NMAX];
int IND[NMAX], T[NMAX];
int SIGMA[256];
char S[NMAX];
FILE * fin, * fout;
int N, K, value, max = 0, i;
int ORDER[NMAX], POW[NMAX];
int COUNT[NMAX];
#define COUNT ( COUNT + 1 )

void sort()
{
	int i;
    for( i = 0; i < N; i++ ) COUNT[i] = 0;
	for( i = 0; i < N; i++ ) COUNT[V[i].last]++;
	for( i = 0; i < N; i++ ) COUNT[i] += COUNT[i-1];
	for( i = 0; i < N; i++ ) T[ COUNT[V[i].last] - 1 ] = i, COUNT[V[i].last]--;
	for( i = 0; i < N; i++) COUNT[i] = 0;
	for( i = 0; i < N; i++ ) COUNT[ V[i].first]++;
	for( i = 0; i < N; i++ ) COUNT[i] += COUNT[i-1];
	for( i = N-1; i >= 0; i-- ) IND[ COUNT[ V[T[i]].first] - 1 ] = T[i], COUNT[V[T[i]].first]--;

}
void SUFFIX_ARRAY()
{
 int i, step, p;
 memset( SIGMA, 0, sizeof(SIGMA) );
 for( i = 0; i < N; i++ ) SIGMA[ S[i] ] = 1;
 for( i = 1; i < 256; i++ ) SIGMA[i] += SIGMA[i-1];
 memset( SUFF, 0, sizeof(SUFF) );
 for( i = 0; i < N; i++ ) SUFF[0][i] = SIGMA[ S[i] ] - 1;
 step = 0;
 do
 {
	 step++;
	 for( i = 0; i < N; i++ )
	 {
		 V[i].first = SUFF[step-1][i];
		 if( i + ( 1 << (step-1) ) < N ) V[i].last = SUFF[step-1][i + ( 1 << (step-1)) ]; else
			                             V[i].last = -1;
	 }
	 sort();
	 p = 0;
	 SUFF[step][ IND[0] ] = 0;
	 for( i = 1; i < N; i++ )
	 {
		 if (( V[IND[i-1]].first != V[IND[i]].first ) || ( V[IND[i-1]].last != V[IND[i]].last ) ) p++;
		 SUFF[step][IND[i]] = p;
	 }
 }while (p < N - 1);
 for( i = 0; i < N; i++ ) ORDER[ SUFF[step][i] ] = i;
}
void RMQ_BUILDING()
{
	int i, p1, p2, j;
 memset( RMQ, 0, sizeof( RMQ ) ); 
  for( i = 0; i < N - 1; i++ )
  {
	  p1 = ORDER[i]; p2 = ORDER[i+1]; RMQ[0][i] = 0;
	  while ( p1 < N && p2 < N && S[p1] == S[p2] ) p1++, p2++, RMQ[0][i]++;
  }
  for( i = 1; i <=  LOGMAX; i++ )
	  for( j = 0; j < N - ( 1 << i ); j++ )
		   RMQ[i][j] = MIN( RMQ[i-1][j], RMQ[i-1][j + ( 1 << (i - 1 ))] );
  memset( POW, 0, sizeof( POW ) );
  for( i = 0; (1 << i ) < N; i++ ) POW[ 1 << i ] = i;
  for( i = 1; i < N; i++ ) 
	  if(!POW[i]) POW[i] = POW[i-1];
}
int query( int x, int y )
{
int	pow = POW[ y - x + 1];
	return MIN( RMQ[pow][x], RMQ[pow][ y - ( 1 << pow ) + 1 ] );
}

int main()
{
	fin = fopen( FIN, "r" );
	fout = fopen( FOUT, "w" );
	fscanf( fin, "%d %d\n", &N, &K );
	fgets( S, NMAX, fin );
	SUFFIX_ARRAY();
	RMQ_BUILDING();
    for( i = K - 1; i < N; i++ )
	{
	    value = query( i - K + 1, i - 1 );
		if ( value > max ) max = value;
	}
	if ( K == 1 ) max = N;
    fprintf( fout, "%d\n", max );
	fclose( fin );
	fclose( fout );
	return 0;
}