Cod sursa(job #1462)

Utilizator victorsbVictor Rusu victorsb Data 13 decembrie 2006 18:58:32
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.91 kb
#include <cstdio>
#include <deque>
#define Nmax 20000

using namespace std;

char sir[Nmax];
int pos[Nmax],prm[Nmax],count[Nmax],bh[Nmax],b2h[Nmax],bucket[200],n,lcp[Nmax],k;

deque<int> q;
deque<int> qpos;

void init()
{
     int i;
     for (i=0;i<n;i++)                                                     
         pos[i]=i;
     for (i=0;i<n;i++)
         bucket[sir[i]]++;
     for (i=0;i<200;i++)
         bucket[i]+=bucket[i-1];
     for (i=n-1;i>=0;i--)
         {
             bucket[sir[i]]--;
             prm[i]=bucket[sir[i]];
         }
     for (i=0;i<n;i++)
         pos[prm[i]]=i;
     bh[0]=1;
     for (i=0;i<n-1;i++)
         if (sir[pos[i]]!=sir[pos[i+1]])
            bh[i+1]=1;
}

void complcp()
{
     int cr=prm[0],i,t=0;
     for (i=1;i<n;i++)
     {
         if (cr>0)
         while (sir[pos[cr]+t]==sir[pos[cr-1]+t])
             t++;
         lcp[pos[cr]]=t;
         if (t>0)
             t--;
         cr=prm[i];
     }
     
     
}

void scrie()
{
     int i,j;
     for (i=0;i<n;i++)
     {
        for (j=pos[i];j<n;j++)
            printf("%c",sir[j]);
        printf(" %d\n",lcp[pos[i]]);
     }
     printf("\n");
}

void solve()
{
     init();
     int i,j,t,l,r,d,e,h;
     for (i=0;i<n;i++)
         if (bh[i])
            prm[pos[i]]=i;
         else
             prm[pos[i]]=prm[pos[i-1]];
     for (h=1;h<n;h*=2)
     {
         for (l=0;l<n;l++)
             if (bh[l])
             {
                 for (r=l+1;r<n&&bh[r]==0;r++);
                 r--;
                 count[l]=0;
                 for (i=l;i<=r;i++)
                     prm[pos[i]]=l;
             }
         d=n-h;
         e=prm[d];
         prm[d]=e+count[e];
         count[e]++;
         b2h[prm[d]]=1;
         for (l=0;l<n;l++)
             if (bh[l])
             {
                 for (r=l+1;r<n&&bh[r]==0;r++);
                 r--;
                 for (i=l;i<=r;i++)
                     if (pos[i]-h>=0)
                     {
                        d=pos[i]-h;
                        e=prm[d];
                        prm[d]=e+count[e];
                        count[e]++;
                        b2h[prm[d]]=1;
                     }
                 for (i=l;i<=r;i++)
                     if (pos[i]-h>=0)
                     {
                        d=pos[i]-h;
                        if (b2h[prm[d]]==1)
                        {
                           for (j=prm[d]+1;j<n;j++)
                               if (bh[j]||(!b2h[j]))
                                  break;
                           e=j;
                           for (j=prm[d]+1;j<e;j++)
                               b2h[j]=0;
                        }
                     }
             }
         for (i=0;i<n;i++)
         {
             pos[prm[i]]=i;
             if (b2h[i]&&(!bh[i]))
                bh[i]=b2h[i];
         }
     }
     complcp();
}

void solve2()
{
     int i,max=0;k--;
     for (i=1;i<=k;i++)
     {
         while (q.size()>0&&q[q.size()-1]>lcp[pos[i]])
         {
               q.pop_back();
               qpos.pop_back();
         }
         q.push_back(lcp[pos[i]]);
         qpos.push_back(i);
         max=q[0];
     }
     for (i=k+1;i<n;i++)
     {
         while (q.size()>0&&i-qpos[0]>=k)
         {
               q.pop_front();
               qpos.pop_front();
         }
         while (q.size()>0&&q[q.size()-1]>lcp[pos[i]])
         {
               q.pop_back();
               qpos.pop_back();
         }
         q.push_back(lcp[pos[i]]);
         qpos.push_back(i);
         if (q[0]>max)
            max=q[0];
     }
     if (k==0) max++;
     printf("%d\n",max);
}

int main()
{
    freopen("substr.in","r",stdin);
    freopen("substr.out","w",stdout);
    scanf("%d %d\n",&n,&k);
    scanf("%s",&sir);
    solve();
    //scrie();
    solve2();
    return 0;
}