Pagini recente » Cod sursa (job #1116335) | Cod sursa (job #3203665) | Cod sursa (job #245384) | Cod sursa (job #498264) | Cod sursa (job #2845369)
#include <bits/stdc++.h>
#define SIGMA 1000
#define NMAX 16384 //saispemii treisute optzeci si patru
using namespace std;
ifstream fin ("substr.in");
ofstream fout ("substr.out");
int RASPUNS_FINAL;
int N, K;
int fr[SIGMA + 1];
int nr[SIGMA + 1];
char s[NMAX + 1];
int lg2[NMAX + 1];
int v[NMAX + 1];
int sA[14 + 1 + 1][NMAX];
pair< pair<int, int>, int > key[NMAX];
void build_lg2(int lim){
lg2[1] = 0;
for(int i = 2; i <= lim; i++){
lg2[i] = lg2[i / 2] + 1;
}
}
int LCP(int i, int j){
int lg = 0;
for(int k = lg2[N]; k >= 0 && i < N && j < N; k--){
if( i + (1 << k) - 1 < N && sA[k][i] == sA[k][j] ){
lg += (1 << k);
i += (1 << k);
j += (1 << k);
}
}
return lg;
}
void build_suffixArray(){
for(int i = 0; i < N; i++){
fr[ s[i] ]++;
}
int dif = 0;
for(int j = 0; j <= SIGMA; j++){
if(fr[j] != 0){
dif++;
nr[j] = dif;
}
}
for(int i = 0; i < N; i++){
sA[0][i] = nr[ s[i] ];
}
for(int i = 1; i <= lg2[N] + 1; i++){
for(int j = 0; j < N; j++){
if( j + (1 << (i - 1) ) < N ){
key[j] = { {sA[i - 1][j], sA[i - 1][j + (1 << (i - 1))]}, j };
}
else {
key[j] = { {sA[i - 1][j], 0}, j };
}
}
sort(key, key + N);
int dist = 0;
for(int j = 0; j < N; j++){
if(j == 0 || key[j].first != key[j - 1].first){
dist++;
}
sA[i][ key[j].second ] = dist;
}
}
for(int j = 0; j < N; j++){
v[ sA[ lg2[N] + 1 ][j] - 1 ] = j;
}
}
void Read(){
fin >> N >> K; fin.get();
fin.getline(s, NMAX + 1);
}
int cautareBinaraStanga(int lo, int hi, int pivot){
lo--;
hi++;
int rsp = -1;
while(hi - lo > 1){
int mid = lo + (hi - lo) / 2;
if( LCP(v[mid], v[pivot]) == 0){
lo = mid;
}
else {
rsp = mid;
hi = mid;
}
}
return rsp;
}
int cautareBinaraDreapta(int lo, int hi, int pivot){
lo--;
hi++;
int rsp = -1;
while(hi - lo > 1){
int mid = lo + (hi - lo) / 2;
if( LCP(v[mid], v[pivot]) == 0){
hi = mid;
}
else {
rsp = mid;
lo = mid;
}
}
return rsp;
}
void Solve(){
int L = -1, R = -1;
for(int p = 0; p < N; p++){
/*if(p <= R){
nu face nimic
}*/
if(p > R) {
L = p;
R = cautareBinaraDreapta(p, N - 1, p);
if(R - L + 1 >= K){
/*
Acum incerc sa gasesc raspunsul meu aici
*/
for(int i = L; i + K - 1 <= R; i++){
int j = i + K - 1;
int candidat = LCP(v[i], v[j]);
if(candidat > RASPUNS_FINAL){
RASPUNS_FINAL = candidat;
}
}
}
}
}
/*
for(int P = 0; P < N; P++){
int st = cautareBinaraStanga( 0, P, P ); //sigur da diferit de -1
int dr = cautareBinaraDreapta( P, N - 1, P ); //sigur da diferit de -1
if(dr - st + 1 >= K){
//atunci este candidat pentru maxim
//fac gen moving window de dimensiune K
for(int i = st; i <= dr - K + 1; i++){
int j = i + K - 1;
int candidat = LCP(v[i], v[j]);
if(candidat > RASPUNS_FINAL){
RASPUNS_FINAL = candidat;
}
}
}
}
*/
}
int main()
{
Read();
if(K > N){
fout << 0 << "\n";
return 0;
}
build_lg2(N);
build_suffixArray();
Solve();
fout << RASPUNS_FINAL << "\n";
return 0;
}