Cod sursa(job #967299)

Utilizator poptibiPop Tiberiu poptibi Data 27 iunie 2013 15:07:13
Problema Substr Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

#define Nmax 17000

struct Data
{
    int PosA, PosB, Idx;
}L[Nmax];

int PosSuffix[15][Nmax], N, K, Step, Cnt, Suffix[Nmax];
char S[Nmax];

struct Comp
{
    bool operator() (Data A, Data B)
    {
        if(A.PosA == B.PosA) return A.PosB < B.PosB;
        return A.PosA < B.PosA;
    }
};

void Build_SA()
{
    for(int i = 1; i <= N; ++ i)
        PosSuffix[0][i] = S[i] - 'a';

    for(Step = Cnt = 1; Cnt <= 2 * N; Cnt *= 2, Step ++)
    {
        for(int i = 1; i <= N; ++ i)
        {
            L[i].PosA = PosSuffix[Step - 1][i];
            L[i].PosB = (i + Cnt <= N ? PosSuffix[Step - 1][i + Cnt] : -1);
            L[i].Idx = i;
        }
        sort(L + 1, L + N + 1, Comp());

        for(int i = 1; i <= N; ++ i)
            PosSuffix[Step][ L[i].Idx ] = (L[i].PosA == L[i - 1].PosA && L[i].PosB == L[i - 1].PosB ? PosSuffix[Step][ L[i - 1].Idx ] : i);
    }
}

int LCP(int X, int Y)
{
    if(X == Y) return N - X;
    int k, Ans = 0;
    for(k = Step - 1; k >= 0 && X <= N && Y <= N; k --)
        if(PosSuffix[k][X] == PosSuffix[k][Y])
        {
            X += (1 << k);
            Y += (1 << k);
            Ans += (1 << k);
        }
    return Ans;
}

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

    scanf("%i %i\n", &N, &K);
    gets(S + 1);

    Build_SA();
    for(int i = 1; i <= N; ++ i)
        Suffix[ PosSuffix[Step - 1][i] ] = i;

    int Ans = 0;
    for(int i = K; i <= N; ++ i)
        Ans = max(Ans, LCP(Suffix[i - K + 1], Suffix[i]));

    printf("%i\n", Ans);
    return 0;
}