Cod sursa(job #2538060)

Utilizator GirafaCuCarapaceGrecuAlexandru GirafaCuCarapace Data 4 februarie 2020 12:41:36
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <bits/stdc++.h>

using namespace std;

const int LOG = 15, N = 17000;

namespace SuffixArray {
    int calc[LOG][N];
    int sa[N], ord[N], lcp[N];
    int n, logn;
    pair < pair < int, int >, int > aux[N];
    string s;

    void Build() {
        n = s.size();
        assert(n != 1);
        for (int i = 0; i < n; ++i)
            calc[0][i] = s[i];
        for (int k = 1; (1<<(k - 1)) < n; ++k) {
            logn = k;
            for (int i = 0; i < n; ++i)
                aux[i] = {{calc[k - 1][i], (i + (1<<(k - 1)) < n ? calc[k - 1][i + (1<<(k - 1))] : -1)}, i};
            sort(aux, aux + n);
            for (int i = 0; i < n; ++i)
                if (i && aux[i].first == aux[i - 1].first)
                    calc[k][aux[i].second] = calc[k][aux[i - 1].second];
                else
                    calc[k][aux[i].second] = i;
        }
        for (int i = 0; i < n; ++i)
            sa[calc[logn][i]] = i, ord[i] = calc[logn][i];
    }

    void Kasai() {
        for (int k = 0, i = 0; i < n; ++i, k?k--:0) {
            if (ord[i] == n - 1) {
                k = 0;
                continue;
            }
            int j = sa[ord[i] + 1];
            while (i + k < n && j + k < n && s[i + k] == s[j + k])
                k++;
            lcp[ord[i]] = k;
        }
    }
}

using namespace SuffixArray;

int dq[N];

int main()
{
    ifstream fin("substr.in");
    ofstream fout("substr.out");
    int n, k;
    fin >> n >> k >> s;
    if (n == 1)
        return fout << 1, 0;
    Build();
    Kasai();
    if (k == 1)
        return fout << n, 0;
    int st(0), dr(-1), ans(0);
    for (int i = 1; i < n; ++i) {
        while (st <= dr && lcp[dq[dr]] >= lcp[i - 1])
            --dr;
        while (st <= dr && dq[st] <= i - k)
            ++st;
        dq[++dr] = i - 1;
        if (i - k >= -1)
            ans = max(ans, lcp[dq[st]]);
    }
    fout << ans;
    return 0;
}