Cod sursa(job #799315)

Utilizator PlayLikeNeverB4George Marcus PlayLikeNeverB4 Data 18 octombrie 2012 17:52:23
Problema Substr Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <ctype.h>
#include <cstring>
#include <ctime>

using namespace std;

#define MAXN 17000
#define MAXLOGN 16
int N, K;
char sir[MAXN];
int P[MAXLOGN][MAXN];
int len;
int rmq[MAXLOGN][MAXN];
int lg[MAXN];
int id[MAXN], sorted[MAXN];

struct sufix {
    int nr[2];
    int p;
} L[MAXN];

bool cmp(const sufix &a, const sufix &b) {
    if(a.nr[0] == b.nr[0])
        return a.nr[1] < b.nr[1];
    return a.nr[0] < b.nr[0];
}

bool cmp2(const int &a, const int &b) {
    return P[len - 1][a] < P[len - 1][b];
}

int encode(char c) {
    if(islower(c))
        return c - 'a';
    if(isupper(c))
        return c - 'A' + 'z' - 'a' + 1;
    return c - '0' + 'z' - 'a' + 1 + 'Z' - 'A' + 1;
}

int slowLCP(int x, int y) {
    int ret = 0;
    for(int k = len - 1; k >= 0 && x < N && y < N; k--)
        if(P[k][x] == P[k][y]) {
            ret += 1 << k;
            x += 1 << k;
            y += 1 << k;
        }
    return ret;
}

int query(int st, int dr) {
    int lung = lg[dr - st + 1];
    return min(rmq[lung][st], rmq[lung][dr - (1 << lung) + 1]);
}

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

    scanf("%d %d\n", &N, &K);

    if(K == 1) {
        printf("%d", N);
        return 0;
    }

    if(N == 1) {
        printf("0");
        return 0;
    }

    fgets(sir, sizeof(sir), stdin);

    for(int i = 0; i < N; i++)
        P[0][i] = encode(sir[i]);

    for(len = 1; (1 << (len - 1)) < N; len++) {
        for(int i = 0; i < N; i++) {
            L[i].nr[0] = P[len - 1][i];
            if(i + (1 << (len - 1)) < N)
                L[i].nr[1] = P[len - 1][i + (1 << (len - 1))];
            else
                L[i].nr[1] = -1;
            L[i].nr[2] = i;
        }
        sort(L, L + N, cmp);
        for(int i = 0; i < N; i++)
            if(i > 0 && L[i - 1].nr[0] == L[i].nr[0] && L[i - 1].nr[1] == L[i].nr[1])
                P[len][L[i].p] = P[len][L[i - 1].p];
            else
                P[len][L[i].p] = i;
    }

    for(int i = 0; i < N; i++)
        id[i] = i;
    sort(id, id + N, cmp2);

    for(int i = 0; i < N - 1; i++)
        rmq[1][i] = slowLCP(id[i], id[i + 1]);
    rmq[1][N - 1] = rmq[1][N - 2];

    for(int k = 1; (1 << (k + 1)) <= N; k++)
        for(int i = 0; i + (1 << (k + 1)) <= N; i++)
            rmq[k + 1][i] = min(rmq[k][i], rmq[k][i + (1 << k)]);

    lg[1] = 0;
    for(int i = 2; i <= N; i++)
        lg[i] = lg[i / 2] + 1;

    int ans = 0;
    for(int i = 0; i <= N - K; i++)
        ans = max(ans, query(i, i + K - 1));

    /*int ans = 0;
    for(int i = 0; i <= N - K; i++)
        ans = max(ans, slowLCP(id[i], id[i + K - 1]));
    */

    printf("%d", ans);

	return 0;
}