Cod sursa(job #290174)

Utilizator flamecataCiobanu Alexandru-Catalin flamecata Data 27 martie 2009 16:34:09
Problema Substr Scor 100
Compilator cpp Status done
Runda aa Marime 2.56 kb
#include <cstdio>     
#include <cstring>     
#include <algorithm>     
     
using namespace std;     
     
struct keys {     
    int x, y, p;     
     
    keys (int _x = 0, int _y = 0, int _p = 0) :     
    x(_x), y(_y), p(_p) {}     
     
    bool operator==(keys b) {     
        return x == b.x && y == b.y;     
    }     
};     
     
const int LGMAX = 14;     
const int NMAX = (1 << LGMAX) + 1;     
     
int N, K, L;     
char S[NMAX];     
int A[LGMAX][NMAX], V[NMAX];     
keys T[NMAX], C[NMAX];     
     
void read(void) {     
    FILE *fin = fopen("substr.in", "rt");     
     
    fscanf(fin, " %d %d", &N, &K);     
     
    fscanf(fin, " %s", S);     
     
    fclose(fin);     
}     
     
void rsort(keys T[], int t) {     
    int i;     
     
    memset(V, 0x00, sizeof(V));     
     
    for (i = 0; i < N; ++i)     
        ++V[ t ? T[i].y : T[i].x ];     
         
    for (i = 1; i <= N; ++i)     
        V[i] += V[i - 1];     
         
    for (i = N-1; i >= 0; --i)     
        C[ -- V[ t ? T[i].y : T[i].x ] ] = T[i];     
     
    memcpy(T, C, sizeof(C));     
}     
     
void build(void) {     
    int i, is, stp, t;     
     
    for (i = 0; i < N; ++i)     
        V[ (int) S[i] ] = 1;     
    for (i = 1; i < 256; ++i)     
        V[i] += V[i-1];     
    for (i = 0; i < N; ++i)     
        A[0][i] = V[ (int) S[i] ];     
     
    t = V[255];     
    for (stp = 1, is = 1; stp < N && t != N; stp <<= 1, ++is) {     
             
        for (i = 0; i < N; ++i)     
            T[i] = keys(A[is-1][i], (i + stp < N ? A[is-1][i+stp] : 0), i);     
     
        rsort(T, 1);     
        rsort(T, 0);     
     
        A[is][ T[0].p ] = t = 1;     
        for (i = 1; i < N; ++i)     
            A[is][ T[i].p ] = t += !(T[i] == T[i-1]);     
    }     
    L = is - 1;     
}     
     
int lcp(int x, int y) {     
    if (x == y) return N - x;     
    int k, ret = 0;     
     
    for (k = L; k >= 0; --k)     
        if (A[k][x] == A[k][y])     
            ret += 1 << k, x += 1 << k, y += 1 << k;     
     
    return ret;     
}     
     
void write(void) {     
    FILE *fout = fopen("substr.out", "wt");     
    int i, R = 0;     
     
    for (i = 0; i <= N - K; ++i)     
        R = max(R, lcp(T[i].p, T[i + K - 1].p));     
     
    fprintf(fout, "%d\n", R);     
     
    fclose(fout);     
}     
     
int main(void) {     
     
    read();     
     
    build();     
     
    write();     
     
return 0;}