Cod sursa(job #2191442)

Utilizator felixiPuscasu Felix felixi Data 2 aprilie 2018 20:35:16
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("substr.in");
ofstream out("substr.out");

const int NMAX = 16400;

struct SuffixArray
{
    static const int LGMAX = 210005;
    static const int LOG = 16;

    int N;
    string str;
    vector<int> toSort;
    pair<int,int> aux[NMAX+2];
    int classes[LOG][NMAX+2];

    SuffixArray(string _str)
    {
        str = _str;
        N = (int)str.size();
        toSort = vector<int>(N);
    }

    vector<int> makeSuffixArray()
    {
        for( int i = 0;  i < N;  ++i ) {
            classes[0][i] = str[i];
            toSort[i] = i;
        }
        for( int j = 1;  j < LOG;  ++j ) {
            for( int i = 0;  i < N;  ++i )
                aux[i] = {classes[j - 1][i], i + (1 << j)/2 < N ? classes[j - 1][i + (1 << j)/2] : -1};
            sort(toSort.begin(), toSort.end(), [&](const int& a, const int& b){
                return aux[a] < aux[b];
            });
            for( int i = 0;  i < N;  ++i )
                classes[j][ toSort[i] ] = (i == 0 ? 1 : classes[j][ toSort[i - 1] ] + (aux[ toSort[i - 1] ] != aux[ toSort[i] ]));
        }
        return toSort;
    }

    int LCP(int a, int b)
    {
        int ans = 0, step = LOG - 1;
        while(step >= 0) {
            if( classes[step][a] == classes[step][b] && a + (1 << step) <= N && b + (1 << step) <= N ) {
                ans += (1 << step);
                a += (1 << step);
                b += (1 << step);
            }
            --step;
        }
        return ans;
    }
};

int main()
{
    string str;
    int N, K;
    in >> N >> K;
    in >> str;
    SuffixArray SA(str);
    auto toSort = SA.makeSuffixArray();

    int best = 0;
    for( int i = 1;  i <= N - K + 1;  ++i ) {
      ///  cerr << i << ' ' << toSort[i - 1] << ' ' << toSort[i + K - 2] << '\n';
        best = max(best, SA.LCP(toSort[i - 1], toSort[i + K - 2]));
    }
    out << best << '\n';
    return 0;
}