Mai intai trebuie sa te autentifici.

Cod sursa(job #3359619)

Utilizator rares89_Dumitriu Rares rares89_ Data 1 iulie 2026 01:11:15
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, k;
string s;
vector<int> sa, rnk, tmp, lcp;

void buildSuffixArray() {
    sa.resize(n);
    rnk.resize(n);
    tmp.resize(n);

    for (int i = 0; i < n; ++i) {
        sa[i] = i;
        rnk[i] = s[i];
    }

    for (int len = 1; len < n; len <<= 1) {
        sort(sa.begin(), sa.end(), [&](int a, int b) {
            if (rnk[a] != rnk[b])
                return rnk[a] < rnk[b];

            int ra = a + len < n ? rnk[a + len] : -1;
            int rb = b + len < n ? rnk[b + len] : -1;

            return ra < rb;
        });

        tmp[sa[0]] = 0;

        for (int i = 1; i < n; ++i) {
            int a = sa[i - 1];
            int b = sa[i];

            int a1 = rnk[a];
            int b1 = rnk[b];

            int a2 = a + len < n ? rnk[a + len] : -1;
            int b2 = b + len < n ? rnk[b + len] : -1;

            tmp[b] = tmp[a] + (a1 != b1 || a2 != b2);
        }

        for (int i = 0; i < n; ++i)
            rnk[i] = tmp[i];
    }
}

void buildLcp() {
    lcp.resize(n);

    for (int i = 0; i < n; ++i)
        rnk[sa[i]] = i;

    int h = 0;

    for (int i = 0; i < n; ++i) {
        int pos = rnk[i];

        if (pos == 0)
            continue;

        int j = sa[pos - 1];

        while (i + h < n && j + h < n && s[i + h] == s[j + h])
            ++h;

        lcp[pos] = h;

        if (h)
            --h;
    }
}

int main() {
    fin >> n >> k;
    fin >> s;

    if (k == 1) {
        fout << n << "\n";
        return 0;
    }

    buildSuffixArray();
    buildLcp();

    int ans = 0;
    deque<int> dq;

    for (int i = 1; i < n; ++i) {
        while (!dq.empty() && lcp[dq.back()] >= lcp[i])
            dq.pop_back();

        dq.push_back(i);

        while (!dq.empty() && dq.front() <= i - (k - 1))
            dq.pop_front();

        if (i >= k - 1)
            ans = max(ans, lcp[dq.front()]);
    }

    fout << ans << "\n";

    return 0;
}