Cod sursa(job #1680163)

Utilizator GinguIonutGinguIonut GinguIonut Data 8 aprilie 2016 15:52:00
Problema Substr Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 1.54 kb
#include <fstream>
#include <algorithm>

#define nMax 16400
#define lgMax 23
using namespace std;
ifstream fin("substr.in");
ofstream fout("substr.out");
int n, k, Sol, stp, cnt;
int P[lgMax][nMax], Prec[nMax];
char S[nMax];

struct sufixe
{
    int p;
    int nr[2];
}L[nMax];
int cmp(const sufixe &a, const sufixe &b)
{
    return (a.nr[0]==b.nr[0] ? a.nr[1]<b.nr[1] : a.nr[0]<b.nr[0]);
}
void read()
{
    fin>>n>>k;

    fin>>S+1;
}
void suffix_array()
{
    for(int i=1;i<=n;i++)
        P[0][i]=S[i]-'a';

    for(stp=1, cnt=1;(cnt >> 1)<=n;stp++, cnt <<= 1)
    {
        for(int i=1;i<=n;i++)
        {
            L[i].nr[0]=P[stp-1][i];
            L[i].nr[1]=(i+cnt<=n ? P[stp-1][i+cnt] : -1);
            L[i].p=i;
        }

        sort(L+1, L+n+1, cmp);

        for(int i=1;i<=n;i++)
            P[stp][L[i].p]=(i>1 && L[i-1].nr[0]==L[i].nr[0] && L[i-1].nr[1]==L[i].nr[1] ? P[stp][L[i-1].p] : i);
    }

    stp--;
}
int query(int a, int b)
{
    int k, ans=0;
    if(a==b)
        return n-a+1;

    for(k=stp;k>=0 && a<=n && b<=n;k--)
    {
        if(P[k][a]==P[k][b])
        {
            ans+=(1 << k);
            a+=(1 << k);
            b+=(1 << k);
        }
    }

    return ans;
}
void solve()
{
    suffix_array();

    for(int i=1;i<=n;i++)
        Prec[P[stp][i]]=i;

    for(int i=1;i<=n-k+1;i++)
        Sol=max(Sol, query(Prec[i], Prec[i+k-1]));
}
void write()
{
    fout<<Sol;
}
int main()
{
    read();
    solve();
    write();

    return 0;
}