Pagini recente » Cod sursa (job #1346312) | Monitorul de evaluare | Cod sursa (job #1731015) | Cod sursa (job #763924) | Cod sursa (job #1597736)
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define MAX_N 16384
#define MIN(A, B) ((A) < (B) ? (A) : (B))
char S[MAX_N + 1];
// pentru Suffix Array
int order[MAX_N];
int SA[MAX_N];
int classes[MAX_N];
int C[MAX_N];
int FRQ[MAX_N];
int SATMP[MAX_N];
struct Scmp {
inline
bool operator () ( const int &A, const int &B ) const {
return S[A] < S[B];
}
};
// pentru LCP
int RANK[MAX_N];
int LCP[MAX_N];
int RMQ[15][MAX_N];
int LOG[MAX_N];
int main() {
FILE *fin, *fout;
int N, K;
fin = fopen( "substr.in", "r" );
fscanf( fin, "%d%d\n", &N, &K );
fgets( S, MAX_N + 1, fin );
fclose( fin );
// Suffix Array
for ( int i = 0; i < N; i++ ) {
order[i] = N - i - 1;
}
std::sort( order, order + N, Scmp() );
for ( int i = 0; i < N; i++ ) {
SA[i] = order[i];
classes[i] = static_cast <int> (S[i]);
}
for ( int length = 1; length < N; length <<= 1 ) {
memmove( C, classes, 4 * N );
for ( int i = 0; i < N; i++ ) {
classes[SA[i]] = i > 0 && C[SA[i-1]] == C[SA[i]] && SA[i-1] + length < N && C[SA[i-1] + (length >> 1)] == C[SA[i] + (length >> 1)] ? classes[SA[i-1]] : i;
}
for ( int i = 0; i < N; i++ ) {
FRQ[i] = i;
}
memmove( SATMP, SA, 4 * N );
for ( int i = 0; i < N; i++ ) {
int S1 = SATMP[i] - length;
if ( S1 >= 0 ) {
SA[ FRQ[classes[S1]]++ ] = S1;
}
}
}
for ( int i = 0; i < N; i++ )
RANK[SA[i]] = i;
int height = 0;
for ( int i = 0; i < N; i++ ) {
int k = RANK[i];
if ( k > 0 ) {
int j = SA[k-1];
while ( S[i + height] == S[j + height] )
height++;
LCP[k] = height;
height -= ( height > 0 );
}
}
for ( int i = 0; i < N; i++ ) {
RMQ[0][i] = LCP[i];
}
for ( int i = 1; ( 1 << i ) < N; i++ ) {
for ( int j = 0; j < N; j++ )
RMQ[i][j] = MIN( RMQ[i-1][j], RMQ[i-1][j + (1<<(i-1))] );
}
int logK = 31 - __builtin_clz( K );
int ret = 0;
for ( int i = 0; i < N - K + 1; i++ ) {
int lcp = ( K == 1 ) ? N - i : MIN( RMQ[logK][i], RMQ[logK][i + K - 1 + (1 << logK)] );
if ( lcp > ret )
ret = lcp;
}
fout = fopen( "substr.out", "w" );
fprintf( fout, "%d\n", ret );
fclose( fout );
return 0;
}