Cod sursa(job #57420)

Utilizator stef2nStefan Istrate stef2n Data 1 mai 2007 23:11:22
Problema Substr Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 kb
#include <cstdio>

#define NMAX 16384
#define LOGMAX 16
struct entry {short int poz,label[2];};

int N,K;
char sir[NMAX+2];
short int P[LOGMAX][NMAX],level;
entry E[NMAX],F[NMAX];
short int count[NMAX],poz[NMAX];
short int ordine[NMAX];

void rsort(entry (&E)[NMAX], entry (&F)[NMAX], int k, bool special)
  {
   int i;
   if(special)
      for(i=0;i<=N || i<128;i++)
         count[i]=0;
   else
      for(i=0;i<=N;i++)
         count[i]=0;
   for(i=0;i<N;i++)
      count[E[i].label[k]]++;
   poz[0]=0;
   if(special)
      for(i=1;i<=N || i<128;i++)
         poz[i]=poz[i-1]+count[i-1];
   else
      for(i=1;i<=N;i++)
         poz[i]=poz[i-1]+count[i-1];
   for(i=0;i<N;i++)
      F[poz[E[i].label[k]]++]=E[i];
  }

void radixsort(bool special)
  {
   rsort(E,F,1,special);
   rsort(F,E,0,special);
  }

void suffix_array()
  {
   int i,j,pas;
   for(j=0;j<N;j++)
      P[0][j]=sir[j]-'0'+1;
   for(i=1,pas=1;pas<N;++i,pas<<=1)
      {
       for(j=0;j<N;j++)
          {
           E[j].poz=j;
           E[j].label[0]=P[i-1][j];
           if(j+pas>=N)
             E[j].label[1]=0;
           else
             E[j].label[1]=P[i-1][j+pas];
          }
       radixsort(i==1);
       int cnt=0;
       P[i][E[0].poz]=0;
       for(j=1;j<N;j++)
          {
           if(E[j].label[0]!=E[j-1].label[0] || E[j].label[1]!=E[j-1].label[1])
             cnt++;
           P[i][E[j].poz]=cnt;
          }
      }
   level=i-1;
  }

int lcp(int a, int b)
  {
   int i,lung=0;
   for(i=level-1;i>=0 && a<N && b<N;--i)
      if(P[i][a]==P[i][b])
        {
         lung+=(1<<i);
         a+=(1<<i);
         b+=(1<<i);
        }
   return lung;
  }


int main()
{

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

int i,max=-1;
scanf("%d %d\n%s",&N,&K,&sir);
suffix_array();
for(i=0;i<N;i++)
   ordine[P[level][i]]=i;
for(i=0;i<=N-K;i++)
   {
    int asem=lcp(ordine[i],ordine[i+K-1]);
    if(max<asem)
      max=asem;
   }
printf("%d\n",(max==-1)?0:max);

return 0;
}