Pagini recente » Cod sursa (job #1639971) | Cod sursa (job #3004507) | Cod sursa (job #1318803) | Cod sursa (job #1763015) | Cod sursa (job #81808)
Cod sursa(job #81808)
#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;
}
fprintf( fout, "%d\n", max );
fclose( fin );
fclose( fout );
return 0;
}