Cod sursa(job #113917)

Utilizator sealTudose Vlad seal Data 11 decembrie 2007 21:40:32
Problema Substr Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include<stdio.h>
#define Nm (1<<14)
char S[Nm],Bh[Nm];
int A[Nm],P[Nm],Bucket[Nm],Cnt[Nm],Lcp[Nm],n,k;

void read()
{
    freopen("substr.in","r",stdin);
    scanf("%d%d%s",&n,&k,S);
}

void suffix_sort()
{
    int i,h,j,s,go_on;

    for(i=0;i<n;++i)
        ++Cnt[S[i]];
    for(i=1;i<256;++i)
        Cnt[i]+=Cnt[i-1];
    for(i=n-1;i>=0;--i)
        A[--Cnt[S[i]]]=i;
        
    for(Bh[0]=i=1;i<n;++i)
    {
        P[A[i]]=i;
        Bh[i]=S[A[i]]!=S[A[i-1]];
    }

    for(go_on=h=1;h<n && go_on;h<<=1)
    {
        for(i=0;i<n;++i)
        {
            if(Bh[i])
                j=i, Cnt[i]=0;
            Bucket[A[i]]=j;
        }

        for(i=0;i<n;++i)
        {
            s=A[i]-h;
            if(s<0)
                continue;
            j=Bucket[s];
            P[s]=j+Cnt[j]++;
        }

        for(i=0;i<n;++i)
            A[P[i]]=i;

        for(go_on=0,i=1;i<n;++i)
        {
            Bh[i]=Bh[i] || A[i]+h>=n || A[i-1]+h
                        || Bucket[A[i]+h]!=Bucket[A[i-1]+h];
            if(!Bh[i])
                go_on=1;
        }
    }
}

void compute_lcp()
{
    int i,next,j=0;

    for(i=0;i<n;++i)
    {
        if(P[i]==n-1)
            continue;
        next=A[P[i]+1];
        while(i+j<n && next+j<n && S[i+j]==S[next+j])
            ++j;
        Lcp[P[i]]=j;
        if(j)
            --j;
    }
}

int ok(int m)
{
    int i,j;

    for(j=1,i=0;i<n;++i,j=1)
    {
        while(j<k && i<n-1 && Lcp[i]>=m)
            ++i, ++j;
        if(j>=k)
            return 1;
    }
    return 0;
}

int solve()
{
    int l,r,m;

    if(k==1)
        return n;

    suffix_sort();
    compute_lcp();

    l=0; r=n;
    while(l<r)
    {
        m=l+r+1>>1;
        if(ok(m))
            l=m;
        else
            r=m-1;
    }
    return l;
}

void write(int ans)
{
    freopen("substr.out","w",stdout);
    printf("%d\n",ans);
}

int main()
{
    read();
    write(solve());
    return 0;
}