Cod sursa(job #141516)

Utilizator BuniakovskiNeguletu Octavian Buniakovski Data 23 februarie 2008 12:41:42
Problema Substr Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.32 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 || 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;   
}