Cod sursa(job #1563313)

Utilizator retrogradLucian Bicsi retrograd Data 5 ianuarie 2016 21:41:33
Problema Substr Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.71 kb
#include <iostream>
#include <algorithm>

using namespace std;

#define MAXN   70007
#define MAXLOG 18

int Sort[MAXN], Class[MAXLOG][MAXN], RMQ[MAXLOG][MAXN], Log[MAXN];
pair<int, int> Aux[MAXN];
char str[MAXN];
int n, k;

void build_sa() {
    for(int i=1; i<=n; i++) {
        Aux[i] = {str[i], 0};
        Sort[i] = i;
    }

    for(int i=0; (1<<i)<=n; i++) {
        sort(Sort+1, Sort+n+1, [](int a, int b) {
            return Aux[a] < Aux[b];
        });

        for(int j=1; j<=n; j++) {
            Class[i][Sort[j]] = Class[i][Sort[j-1]];
            if(Aux[Sort[j]] != Aux[Sort[j-1]])
                Class[i][Sort[j]] += 1;
        }

        for(int j=1; j<=n; j++) {
            Aux[j] = {Class[i][j], Class[i][j + (1 << i)]};
        }
    }
}

void build_heights() {
    for(int i=1; i<n; i++) {
        int a = Sort[i], b = Sort[i+1];

        int j, k = 0;
        for(j=0; (1<<j)<=n; j++);
        for(j--; j>=0; j--) {
            if(Class[j][a] == Class[j][b])
                k += (1 << j), a += (1 << j), b += (1 << j);
        }

        RMQ[0][i] = k;
    }
}

int build_rmq() {
    for(int i=2; i<=n; i++)
        Log[i] = Log[i/2] + 1;

    for(int i=1; (1<<i)<=n; i++)
        for(int j=1; j+(1<<i)<=n; j++)
            RMQ[i][j] = min(RMQ[i-1][j], RMQ[i-1][j+(1<<(i-1))]);
}

int lcp(int a, int b) {
    if(a > b) swap(a, b);
    b--;
    int l = Log[b-a+1];

    return min(RMQ[l][a], RMQ[l][b-(1<<l)+1]);
}



int main() {
    freopen("substr.in", "r", stdin);
    freopen("substr.out", "w", stdout);

    cin >> n >> k >> str + 1;
    build_sa();
    build_heights();
    build_rmq();

    int ans = 0;
    for(int i=k; i<=n; i++) {
        ans = max(ans, lcp(i-k+1, i));
    }
    cout << ans;

    return 0;
}