Cod sursa(job #756955)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 10 iunie 2012 19:52:28
Problema Substr Scor 100
Compilator cpp Status done
Runda Remember Mihai Pătrașcu Marime 1.96 kb
#include <cstdio>
#include <algorithm>

#define NMax 17000
#define LogMax 16

using namespace std;

struct Suffix
{
    int s[2], p;
};

int N, K, P[LogMax][NMax], Log[NMax], Solution;
Suffix S[NMax];

inline bool Compare (const Suffix &S1, const Suffix &S2)
{
    if (S1.s[0]==S2.s[0]) return S1.s[1]<S2.s[1];
    return S1.s[0]<S2.s[0];
}

inline bool Equal (Suffix &S1, Suffix &S2)
{
    return (S1.s[0]==S2.s[0] and S1.s[1]==S2.s[1]);
}

void BuildLog ()
{
    for (int i=2; i<=N; ++i) Log[i]=Log[i/2]+1;
}

void BuildSA ()
{
    BuildLog ();
    for (int Step=1; Step-1<=Log[N]; ++Step)
    {
        for (int i=0; i<N; ++i)
        {
            S[i].s[0]=P[Step-1][i];
            if (i+(1<<(Step-1))<N) S[i].s[1]=P[Step-1][i+(1<<(Step-1))];
            else S[i].s[1]=-1;
            S[i].p=i;
        }
        sort (S, S+N, Compare);
        for (int i=0; i<N; ++i)
        {
            if (i>0 and Equal (S[i], S[i-1])) P[Step][S[i].p]=P[Step][S[i-1].p];
            else P[Step][S[i].p]=i;
        }
    }
}

inline int LCP (int X, int Y)
{
    int R=0;
    if (X==Y) return N-X;
    for (int Step=Log[N]; Step>=0 and X<N and Y<N; --Step)
    {
        if (P[Step][X]==P[Step][Y])
        {
            R+=(1<<Step), X+=(1<<Step), Y+=(1<<Step);
        }
    }
    return R;
}

void Solve ()
{
    BuildSA ();
    for (int i=0; i+K-1<N; ++i)
    {
        Solution=max (Solution, LCP (S[i].p, S[i+K-1].p));
    }
}

inline int Convert (char X)
{
    if (X<='9') return X-'0';
    if (X<='Z') return X-'A'+10;
    if (X<='z') return X-'a'+36;
}

void Read ()
{
    freopen ("substr.in", "r", stdin);
    scanf ("%d %d\n", &N, &K);
    for (int i=0; i<N; ++i)
    {
        char C; scanf ("%c", &C); P[0][i]=Convert (C);
    }
}

void Print ()
{
    freopen ("substr.out", "w", stdout);
    printf ("%d\n", Solution);
}

int main ()
{
    Read ();
    Solve ();
    Print ();
    return 0;
}