Cod sursa(job #1797370)

Utilizator andrei.arnautuAndi Arnautu andrei.arnautu Data 4 noiembrie 2016 12:22:05
Problema Substr Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.07 kb
/**
  *  Worg
  */
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
FILE *fin = freopen("substr.in", "r", stdin);
FILE *fout = freopen("substr.out", "w", stdout);

const int MAX_N = 16500;
const int MAX_LOG = 1 + 15;
int Zero = 0;

/*-------- Input data --------*/
int N, K;
char s[MAX_N];
/*-------- Suffix Arrays --------*/
int Index[MAX_LOG][MAX_N];
int id1[MAX_N], id2[MAX_N], Count[MAX_N];
/*-------- --------*/

int& index(const int &i, const int &j) {
    if(j < MAX_N) {
        return Index[i][j];
    } else {
        return Zero;
    }
}

void readInput() {
    scanf("%d%d", &N, &K);
    scanf("%s", s);
    s[N ++] = '$';
    s[N] = 0;
}

void getSuffixArrays() {
    for(int i = 0; i < N; i++) {
        Count[(int)s[i]] ++;
    }
    for(int i = 0, j = 0; i < 256; i++) {
        if(Count[i]) {
            Count[i] = j ++;
        }
    }
    for(int i = 0; i < N; i++) {
        index(0, i) = Count[(int)s[i]];
    }

    for(int j = 1, L = 1; j < MAX_LOG; j++, L <<= 1) {
        /* construim id1 */
        for(int i = 0; i < N; i++) {
            Count[i] = 0;
        }
        for(int i = 0; i < N; i++) {
            Count[index(j - 1, i + L)] ++;
        }
        for(int i = 1; i < N; i++) {
            Count[i] += Count[i - 1];
        }
        for(int i = N - 1; i >= 0; i--) {
            id1[-- Count[index(j - 1, i + L)]] = i;
        }

        /* construim id2 */
        for(int i = 0; i < N; i++) {
            Count[i] = 0;
        }
        for(int i = 0; i < N; i++) {
            Count[index(j - 1, i)] ++;
        }
        for(int i = 1; i < N; i++) {
            Count[i] += Count[i - 1];
        }
        for(int i = N - 1; i >= 0; i--) {
            id2[-- Count[index(j - 1, id1[i])]] = id1[i];
        }

        index(j, id2[0]) = 0;
        for(int i = 1; i < N; i++) {
            if(index(j - 1, id2[i]) == index(j - 1, id2[i - 1]) &&
                            index(j - 1, id2[i] + L) == index(j - 1, id2[i - 1] + L)) {
                index(j, id2[i]) = index(j, id2[i - 1]);
            } else {
                index(j, id2[i]) = index(j, id2[i - 1]) + 1;
            }
        }
    }

    for(int i = 0; i < N; i++) {
        id1[index(MAX_LOG - 1, i)] = i;
    }
}

int getLCP(int a, int b) {
    int Answer = 0;
    for(int j = MAX_LOG - 1, L = (1 << (MAX_LOG - 1)); j >= 0; j--, L >>= 1) {
        if(index(j, a) == index(j, b)) {
            Answer += L;
            a += L;
            b += L;
        }
    }

    return Answer;
}

void testSA() {
    for(int i = 0; i < N; i++) {
        printf("%s\n", s + id1[i]);
    }
}

int getSolution() {
    int Solution = 0;
    for(int i = 1; i + K - 1 < N; i++) {
        Solution = max(Solution, getLCP(id1[i], id1[i + K - 1]));
    }
   /* for(int i = 0; i + K - 1 < N; i++) {
        printf("%d\n", getLCP(id1[i], id1[i + K - 1]));
    } */
    return Solution;
}

int main() {
    readInput();
    getSuffixArrays();
    printf("%d", getSolution());
    return 0;
}