Cod sursa(job #2450838)

Utilizator AlexandruabcdeDobleaga Alexandru Alexandruabcde Data 24 august 2019 17:54:20
Problema Substr Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.65 kb
#include <bits/stdc++.h>

using namespace std;

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

constexpr int NMAX = 16390;

int n, k;

char ch[NMAX];
int a[NMAX];

int ind[300];

pair <int, int> cod[NMAX];
pair <pair <int, int>, int> v[NMAX];
map <char, bool> mp;

int pre[22][NMAX];

int sir[NMAX];

void Suffix_Array()
{
    for (int i=1; i<=n; ++i)
        mp[ch[i]]=1;
    int cnt=0;

    for (auto it:mp)
    {
        ++cnt;
        ind[(int)it.first]=cnt;
    }

    for (int i=1; i<=n; ++i)
        pre[0][i]=ind[(int)ch[i]];

    for (int i=1; i<=20; ++i)
    {
        for (int j=1; j<=n; ++j)
            cod[j] = {pre[i-1][j], (j + (1<<(i-1)) <= n ? pre[i-1][j+(1<<(i-1))] : 0)};

        for (int j=1; j<=n; ++j)
            v[j] = {cod[j], j};

        sort (v+1, v+n+1);

        int cnt=0;
        for (int j=1; j<=n; ++j)
        {
            if (v[j-1].first != v[j].first)
                ++cnt;

            pre[i][v[j].second] = cnt;
        }
    }
}

int LCP (int st, int dr)
{
    int dim=min(n-st+1, n-dr+1);
    int rez=0;

    for (int i=log2(dim); i>=0 && st <= n && dr <= n; --i)
    {
        if (pre[i][st] != pre[i][dr]) continue;

        rez += (1<<i);
        st += (1<<i);
        dr += (1<<i);
    }

    return rez;
}

void Solve()
{
    for (int i=1; i<=n; ++i)
        sir[pre[20][i]] = i;

    int sol=0;

    for (int i=1; i<=n-k+1; ++i)
        sol = max(sol, LCP(sir[i], sir[i+k-1]));

    g << sol << '\n';
}

int main()
{
    f >> n >> k;
    for (int i=1; i<=n; ++i)
        f >> ch[i];

    Suffix_Array();
    Solve();
    return 0;
}