Pagini recente » Clasament teme_acmunibuc_2013 | Cod sursa (job #2757940) | Cod sursa (job #1273772) | Cod sursa (job #1136567) | Cod sursa (job #2846946)
// This program was written on 09.02.2022
// for problem substr
// by Mircea Rebengiuc
// ans = max( minimum sliding window de lungime K-1 pe lcp[] )
#include <stdio.h>
#include <ctype.h>
#define MAXN 16'384
#define MAXL 14
#define NIL -1
char str[MAXN + 1];
// sufix arrays
int suffarr[2][MAXN + 1];
int id[2][MAXN][2];
int frecv[MAXN];
int poz[MAXN + 1];// santinela la sfarsit
// kasai
int invsuff[MAXN];
int lcp[MAXN];
// minimum over a sliding window
int deq[MAXN];// obs: nu e nevoie de deq circular
int p = 0, u = 0;
int pv = 0, uv = 0;// intervalul in lcp[]
void push(){
while( p != u && deq[u - 1] >= lcp[uv] )
u--;
deq[u++] = lcp[uv++];
}
void pop(){
if( lcp[pv] == deq[p] )
p++;
pv++;
}
int query(){
return deq[p];
}
FILE *fin, *fout;
int main(){
fin = fopen("substr.in", "r");
fout = fopen("substr.out", "w");
int n, k, i, j, t, curr_len, pref, maxcommon, cand;
int prev[2];
fscanf( fin, "%d %d ", &n, &k );
for( i = 0 ; i < n ; i++ ){
str[i] = fgetc( fin );
frecv[(int)str[i]]++;
}
str[n] = '\0';
// suffix arrays
j = 1;
for( i = 0 ; i < 128 ; i++ )
if( frecv[i] )
frecv[i] = j++;
for( i = 0 ; i < n ; i++ ){
suffarr[0][i] = i;
id[0][i][0] = frecv[(int)str[i]];
}
pref = 1;
while( id[0][n - 1][0] < n ){// optimizare
for( i = 0 ; i < n ; i++ )
invsuff[suffarr[0][i]] = i;
for( i = 0 ; i < n ; i++ )
id[0][i][1] = (suffarr[0][i] + pref) < n ? id[0][invsuff[suffarr[0][i] + pref]][0] : 0;
// metoda noua de radix...
for( t = 0 ; t < 2 ; t++ ){// suffarr[t], id[t][][] ----radix----> suffarr[t^1], id[t^1][][]
for( i = 0 ; i < n ; i++ )
poz[i] = frecv[i] = 0;
for( i = 0 ; i < n ; i++ )
poz[id[t][i][t^1] + 1]++;
for( i = 1 ; i < n ; i++ )
poz[i] += poz[i - 1];
for( i = 0 ; i < n ; i++ ){
j = poz[id[t][i][t^1]] + (frecv[id[t][i][t^1]]++);
suffarr[t^1][j] = suffarr[t][i];
id[t^1][j][0] = id[t][i][0];
id[t^1][j][1] = id[t][i][1];
}
}
// refacere coduri
j = 0;
prev[0] = prev[1] = -1;
for( i = 0 ; i < n ; i++ ){
if( prev[0] != id[0][i][0] || prev[1] != id[0][i][1] )
j++;
prev[0] = id[0][i][0];
prev[1] = id[0][i][1];
id[0][i][0] = j;
}
pref <<= 1;
}
// kasai
suffarr[0][n] = n;
for( i = 0 ; i < n ; i++ )
invsuff[suffarr[0][i]] = i;
curr_len = 0;
for( i = 0 ; i < n ; i++ ){
j = suffarr[0][invsuff[i] + 1];
while( str[i + curr_len] == str[j + curr_len] )
curr_len++;
lcp[invsuff[i]] = curr_len;
curr_len = curr_len > 0 ? (curr_len - 1) : 0;
}
// fereastra glisanta de minim...
k--;
n--;
for( i = 1 ; i < k ; i++ )// inseram primele k-1
push();
maxcommon = 0;
for( i = k ; i < n ; i++ ){
push();
cand = query();
maxcommon = cand > maxcommon ? cand : maxcommon;
pop();
}
fprintf( fout, "%d\n", maxcommon );
fclose(fin);
fclose(fout);
return 0;
}