Cod sursa(job #2270)

Utilizator MariusMarius Stroe Marius Data 16 decembrie 2006 18:32:17
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <cstdio>
#include <memory>
#include <algorithm>
using namespace std;

const char iname[] = "substr.in";
const char oname[] = "substr.out";

#define MAX_N  18000
#define MAX_LG 16

char A[MAX_N];
struct entry {
    int nr[2];
    int p;
} L[MAX_N];
int P[MAX_LG][MAX_N], X[MAX_N], Q[MAX_N], R[MAX_N], N, K;

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

int cmp(entry a, entry b) {
    return a.nr[0] == b.nr[0] ? (a.nr[1] < b.nr[1] ? 1 : 0)
                              : (a.nr[0] < b.nr[0] ? 1 : 0);
}

int main(void)
{
    freopen(iname, "r", stdin);
    freopen(oname, "w", stdout);
    int i;
    int stp;
    int cnt;
    int len;
    int head, tail;
    int Res = 0;
    
    scanf("%d %d\n", & N, & K);
    scanf("%s", A);
    for (i = 0; i < N; ++i) {
        if ('0' <= A[i] && A[i] <= '9')
           P[0][i] = A[i] - '0';
        else if ('A' <= A[i] && A[i] <= 'Z')
           P[0][i] = A[i] - 'A' + 10;
       else
           P[0][i] = A[i] - 'a' + 10 + 26;
    }
    for (stp = cnt = 1; cnt >> 1 < N; cnt <<= 1, ++stp) {
        for (i = 0; i < N; ++i) {
            L[i].nr[0] = P[stp - 1][i];
            L[i].nr[1] = i + cnt < N ? P[stp - 1][i + cnt] : -1;
            L[i].p = i;
        }
        sort(L, L + N, cmp);
        for (i = 0; i < N; ++i)
            P[stp][L[i].p] = i > 0 && L[i].nr[0] == L[i - 1].nr[0] &&
                             L[i].nr[1] == L[i - 1].nr[1] ? P[stp][L[i - 1].p] : i;
    }
    for (i = 0; i < N; ++i)
        X[P[stp - 1][i]] = i;

    head = tail = 0;
    for (i = 1; i < N; ++i) {
        len = lcp(stp - 1, X[i - 1], X[i]);
        for (; head < tail && R[head] <= i - K + 1; ++head)
            ;
        for (; head < tail && Q[tail - 1] > len; --tail)
            ;
        Q[tail] = len; 
        R[tail] = i;
        tail += 1;
        if (i > K - 2)
           if (Res < Q[head])
              Res = Q[head];
    }    
    if (K == 1)
       Res = N;
    printf("%d\n", Res);
    
    return 0;
}