Cod sursa(job #1053792)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 12 decembrie 2013 22:56:23
Problema Substr Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.06 kb
#include <fstream>
#include <vector>
#include <algorithm>

#define In "substr.in"
#define Out "substr.out"
#define Nmax 16500
#define LOG 16
#define vect pair < pair < int ,int > ,int >
#define First first.first
#define Second first.second
#define pos second

using namespace std ;
int n, k ,sol, a[Nmax];
char s[Nmax];
vect v[Nmax];
inline int F(const char ch)
{
    if('0' <= ch && ch <= '9')
        return ch - '0';
    if('A' <= ch && ch <= 'Z')
        return ch -'A' + 10;
    return ch-'a' + 10 + 26;
}
struct Suffix_Arrays
{
    int step, P[LOG][Nmax];
    inline void Build()
    {
        int i ,j ,p;
        for(step = 0, p = 1; p <= n; ++step,p <<= 1);
        for(i = 1;i <= n; ++i)
            P[0][i] = F(s[i]);
        for(j = 1,p = 1;j <= step; ++j,p <<= 1)
        {
            for(i = 1;i <= n; ++i)
            {
                v[i].First = P[j-1][i];
                if(i+p <= n)
                    v[i].Second = P[j-1][i+p];
                else
                    v[i].Second = -1;
                v[i].pos = i;
            }
            sort(v+1,v+n+1);
            for(i = 1;i <= n; ++i)
                if(v[i].First == v[i-1].First && v[i].Second == v[i-1].Second)
                    P[j][v[i].pos] = P[j][v[i-1].pos];
                else
                    P[j][v[i].pos] = i;
        }
        for(i = 1;i <= n; ++i)
            a[P[step][i]] = i;
    }
    inline int LCP(int x,int y)
    {
        if(x==y)
            return n-x+1;
        int k,ret = 0, p;
        for(k = step,p = (1<<step);k >= 0  && x <= n && y <= n; --k,p>>=1)
            if(P[k][x] == P[k][y])
            {
                x += p ;
                y += p ;
                ret+= p;
            }
        return ret;
    }
};
Suffix_Arrays S;
inline void Read()
{
    ifstream f(In);
    f>> n >> k >> (s+1);
    f.close();
}

inline void Solve()
{
    S.Build();
    for(int i = 1;i+k-1<= n; ++i)
        sol = max(sol,S.LCP(a[i],a[i+k-1]));
}

inline void Write()
{
    ofstream g(Out);
    g<<sol<<"\n";
    g.close();
}

int main()
{
    Read();
    Solve();
    Write();
    return 0;
}