Cod sursa(job #2845736)

Utilizator PopaMihaimihai popa PopaMihai Data 8 februarie 2022 11:42:18
Problema Substr Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <fstream>
#include <algorithm>
#include <string>
#include <cstring>

using namespace std;

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

const int NMAX = 17e3, INF = 1e9;

typedef pair <int, int> pii;
typedef pair <pii, int> piii;

int Log[NMAX];
int sa[20][NMAX];
piii v[NMAX];
int w[NMAX];
int n, k;

string s;

int mymin(int a, int b)
{
    return (a < b ? a : b);
}

int lcp(int a, int b)
{
    int ans = 0;
    for(int i = Log[n]; i >= 0 && a <= n && b <= n; -- i) {
        if(sa[i][a] == sa[i][b]) {
            ans += (1 << i);
            a += (1 << i);
            b += (1 << i);
        }
    }
    return ans;
}

void build_sa ()
{
    s = '$' + s;
    for(int i = 1; i <= n; ++ i )
        sa[0][i] = (int)s[i];

    for(int i = 1; i <= Log[n] + 2; ++ i) {
        for(int j = 1; j <= n; ++ j) {
            if(j + (1 << (i - 1)) <= n)
                v[j].first = {sa[i - 1][j], sa[i - 1][j + (1 << (i - 1))]};
            else v[j].first = {sa[i - 1][j], 0};
            v[j].second = j;
        }
        sort(v + 1, v + n + 1);
        int cnt = 0;
        for(int j = 1; j <= n; ++ j) {
            if(v[j].first != v[j - 1].first){
                cnt++;
            }
            sa[i][v[j].second] = cnt;
        }
    }

    for(int j = 1; j <= n; ++j)
        w[sa[Log[n] + 2][j]] = j;

}

int main()
{
    Log[1] = 0;
    for(int i = 2; i <= NMAX - 1; ++ i)
        Log[i] = Log[i >> 1] + 1;
    fin >> n >> k;
    fin >> s;
    build_sa();
    long long ans = 0, rasp = 0;
    for(int i = 1; i <= n - k + 1; ++ i) {
        ans = INF;
        for(int j = 0; j < k; ++ j)
            ans = mymin(ans, lcp(w[i], w[i + j]));
        rasp = (rasp > ans ? rasp : ans);
    }


    fout << rasp << '\n';
    return 0;
}