Cod sursa(job #2200138)

Utilizator MaligMamaliga cu smantana Malig Data 30 aprilie 2018 14:07:06
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <bits/stdc++.h>

using namespace std;

#if 1
    #define pv(x) cout<<#x<<" = "<<(x)<<"; ";cout.flush()
    #define pn cout<<endl
#else
    #define pv(x)
    #define pn
#endif

#ifdef INFOARENA
    ifstream in("substr.in");
    ofstream out("substr.out");
#else 
    #define in cin
    #define out cout
#endif

using ll = long long;
using ull = unsigned long long;
using ui = unsigned int;
#define pb push_back
#define mp make_pair
const int NMax = 2e4 + 5;
const ll inf_ll = 1e18 + 5;
const int inf_int = 1e9 + 5;
const int mod = 100003;
using zint = int;

int p[20][NMax];

struct elem {
    int o1, o2, idx;
};

int lcp(int x, int y, int N, int step) {
    if (x == y) return N - x;

    int ans = 0;
    for (int k = step; k >= 0 && x < N && y < N; --k) {
        if (p[k][x] == p[k][y]) {
            ans += 1 << k;
            x += 1 << k;
            y += 1 << k;
        }
    }

    return ans;
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(0);

    int N,K;
    in >> N >> K;
    string str;
    in >> str;
    vector<elem> v(N);
    for (ui i = 0;i < N;++i) {
        p[0][i] = str[i] - 'a';
    }

    // for (ui i = 0; i < N ;++i) {
    //     cout << p[0][i] << ' ';
    // }
    // cout << '\n';

    int pw = 1, step;
    for (step = 1; pw <= N; pw <<= 1, step += 1) {
        for (ui i = 0; i < N; ++i) {
            v[i].o1 = p[step - 1][i];
            v[i].o2 = i + pw < N ? p[step - 1][i + pw] : -1;
            v[i].idx = i;
        }

        auto cmp = [](const elem& a, const elem& b) -> bool {return a.o1 == b.o1 ? a.o2 < b.o2 : a.o1 < b.o1;};

        sort(v.begin(), v.end(), cmp);

        p[step][v[0].idx] = 0;
        for (ui i = 1; i < N ;++i) {
            p[step][v[i].idx] = p[step][v[i-1].idx];
            p[step][v[i].idx] += !(v[i].o1 == v[i-1].o1 && v[i].o2 == v[i-1].o2);
        }
 
        // for (ui i = 0; i < N; ++i) {
        //     cout << v[i].idx << ' ';
        // }
        // cout << '\n';

        // for (ui i = 0; i < N ;++i) {
        //     cout << p[step][i] << ' ';
        // }
        // cout << '\n';
    }
    --step;

    // for (ui i = 0; i < N; ++i) {
    //     out << v[i].idx << ' ';
    // }
    // out << '\n';

    int ans = 0;
    for (int i = 0; i < N - K + 1; ++i) {
        ans = max(ans, lcp(v[i].idx, v[i + K - 1].idx, N, step));
        // pv(v[i].idx); pv(v[i + K - 1].idx); pv(lcp(v[i].idx, v[i + K - 1].idx, N, step)); pn;
    }
    out << ans;

    return 0;
}