Cod sursa(job #597850)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 23 iunie 2011 15:24:13
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <cstdio>
#include <algorithm>

using namespace std;

struct elem {
    int poz, nr[2];
};

const int logN = 19, N = 16400;

elem v[N];

int n, k, logc, P[logN][N];

char s[N];

void read() {
    scanf("%d%d\n", &n, &k);

    scanf("%s", &s);
}

bool comp(const elem &A, const elem &B) {
    return (A.nr[0] == B.nr[0]) ? (A.nr[1] < B.nr[1]) : (A.nr[0] < B.nr[0]);
}

void init_suffix_arrays() {
    for (int i = 0; i < n; ++ i) {
        v[i].nr[1] = s[i];

        v[i].poz = i;
    }

    sort(v, v + n, comp);

    int ic = 0;

    P[0][v[0].poz] = ++ ic;

    for (int i = 1; i < n; ++ i)
        if (v[i].nr[0] == v[i - 1].nr[0] && v[i].nr[1] == v[i - 1]. nr[1])
            P[0][v[i].poz] = ic;
        else
            P[0][v[i].poz] = ++ ic;

    logc = 0;
}

void suffix_arrays() {
    init_suffix_arrays();

    for (int j = 1, p2 = 1; p2 < n; ++ j, p2 <<= 1) {
        for (int i = 0; i < n; ++ i) {
            v[i].nr[0] = P[j - 1][i];

            if (i + p2 < n)
                v[i].nr[1] = P[j - 1][i + p2];
            else
                v[i].nr[1] = - 1;

            v[i].poz = i;
        }

        sort(v, v + n, comp);

        int ic = 0;

        P[j][v[0].poz] = ++ ic;

        for (int i = 1; i < n; ++ i)
            if (v[i].nr[0] == v[i - 1].nr[0] && v[i].nr[1] == v[i - 1]. nr[1])
                P[j][v[i].poz] = ic;
            else
                P[j][v[i].poz] = ++ ic;

        logc = j;
    }
}

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

    int lung = 0;

    for (int k = logc; k >= 0 && x < n && y < n; -- k)
        if (P[k][x] == P[k][y])
            x += (1 << k), y += (1 << k), lung += (1 << k);

    return lung;
}

void solve() {
    for (int i = 0; i < n; ++ i) {
        v[i].nr[0] = P[logc][i];

        if (i + (1 << (logc - 1)) < n)
            v[i].nr[1] = P[logc][i + (1 << (logc - 1))];
        else
            v[i].nr[1] = - 1;

        v[i].poz = i;
    }

    sort(v, v + n, comp);

    int rez = - 1;

    for (int i = 0; i < n - k + 1; ++ i) {
        int lcpc = lcp(v[i].poz, v[i + k - 1].poz);

        if (lcpc > rez)
            rez = lcpc;
    }

    printf("%d\n", rez);
}

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

    read();

    suffix_arrays();

    solve();

    return 0;
}