Cod sursa(job #2628758)

Utilizator CraniXortDumitrescul Eduard CraniXort Data 17 iunie 2020 13:00:49
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <bits/stdc++.h>
#define maxn 16400

std::ifstream fin ("substr.in");
std::ofstream fout ("substr.out");

int suffix[maxn];

struct str{
    int first, second;
    int ind;
};

bool comp (str a, str b){
    if (a.first != b.first)
        return a.first < b.first;
    return a.second < b.second;
}

void suffixArray (std::string &s){
    int i, j, ind[s.size()];
    std::vector <str> v(s.size());

    for (i=0; i<s.size(); i++){
        v[i].first = s[i] - 'a';
        if (i + 1< s.size())
            v[i].second = s[i+1]-'a';
        else
            v[i].second = -1;
        v[i].ind = i;
    }

    std::sort (v.begin(), v.end(), comp);

    for (j=2; j<s.size(); j*=2){
        for (i=0; i<s.size(); i++)
            ind[v[i].ind] = i;
        int rank = v[0].first;
        v[0].first = 0;
        for (i=1; i<s.size(); i++){
            if (v[i].first == rank and v[i].second == v[i-1].second)
                v[i].first = v[i-1].first;
            else{
                rank = v[i].first;
                v[i].first = v[i-1].first + 1;
            }

        }

        for (i=0; i<s.size(); i++){
            int pos = v[i].ind + j;
            if (pos < s.size())
                v[i].second = v[ind[pos]].first;
            else
                v[i].second = -1;
        }

        std::sort (v.begin(), v.end(), comp);
    }

    for (i=0; i<s.size(); i++)
        suffix[i] = v[i].ind;

}

int lcp[maxn];

void Lcp (std::string &s){
    int ind[s.size()], i, j;
    for (i=0; i<s.size(); i++)
        ind[suffix[i]] = i;
    for (i=0, j=0; i<s.size(); i++){
        if (ind[i] == s.size()-1){
            j = 0;
            continue;
        }

        int next = suffix[ind[i]+1];
        while (i+j < s.size() and next+j < s.size() and s[i+j] == s[next+j])
            j++;
        lcp[ind[i]] = j;
        if (j) j--;
    }
}

bool verif (int k, int lenght, std::string &s){
    for (int i=0, j=1; i<s.size(); i++, j=1){
        while (j < k and i <= s.size()-1 and lcp[i] >= lenght)
            i++, j++;
        if (j >= k)
            return true;
    }
    return false;
}

int main()
{
    int n, k, i, j;
    std::string s;
    fin >> n >> k;
    fin >> s;

    suffixArray(s);
    /*
    for (i=0; i<s.size(); i++)
        fout << suffix[i] << ' ';
    fout << '\n';
    for (i=0; i<s.size(); i++){
        for (j=suffix[i]; j<s.size(); j++)
            fout << s[j];
        fout << '\n';
    }


    for (i=0; i<s.size(); i++)
        fout << lcp[i] << ' ';
        */
Lcp (s);
    int left = 1, right = s.size();
    while (left <= right){
        int mid = (left + right) / 2;
        if (verif(k, mid, s) == true)
            left = mid + 1;
        else
            right = mid - 1;
    }
    fout << left-1 << '\n';

    return 0;
}