Cod sursa(job #2845376)

Utilizator NeacsuMihaiNeacsu Mihai NeacsuMihai Data 7 februarie 2022 19:15:21
Problema Substr Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.1 kb
#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[17 + 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);
}

void Solve(){
    for(int i = 0; i + K - 1 < N; i++){
        RASPUNS_FINAL = max(RASPUNS_FINAL, LCP(v[i], v[i + K - 1]));
    }
}

int main()
{
    Read();
    build_lg2(N);
    build_suffixArray();
    Solve();

    fout << RASPUNS_FINAL << "\n";

    return 0;
}