Cod sursa(job #1060953)

Utilizator poptibiPop Tiberiu poptibi Data 18 decembrie 2013 22:35:39
Problema Substr Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 1.83 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;

const int NMAX = 17010;

int N, K, PosSuffix[17][NMAX], Suffix[NMAX], Step, Cnt, Ans;
char S[NMAX];

struct SuffixData
{
    int PosA, PosB, Index;
}SO[NMAX];

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

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

void SortSuffixes()
{
    for(int i = 1; i <= N; ++ i)
        PosSuffix[0][i] = S[i] - 'a';
    for(Step = Cnt = 1; Cnt <= N; Step ++, Cnt *= 2)
    {
        for(int i = 1; i <= N; ++ i)
        {
            SO[i].PosA = PosSuffix[Step - 1][i];
            SO[i].PosB = (i + Cnt <= N ? PosSuffix[Step - 1][i + Cnt] : -1);
            SO[i].Index = i;
        }

        sort(SO + 1, SO + N + 1, Comp());

        for(int i = 1; i <= N; ++ i)
            if(SO[i].PosA == SO[i - 1].PosA && SO[i].PosB == SO[i - 1].PosB)
                PosSuffix[Step][SO[i].Index] = PosSuffix[Step][SO[i - 1].Index];
            else
                PosSuffix[Step][SO[i].Index] = i;
    }
}

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

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

    SortSuffixes();

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

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

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