Cod sursa(job #1567731)

Utilizator BLz0rDospra Cristian BLz0r Data 13 ianuarie 2016 18:16:50
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <fstream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;

#define Nmax 16390
#define Lmax 16

ifstream fin ( "substr.in" );
ofstream fout ( "substr.out" );

int N, P[Lmax][Nmax], Poz[Nmax];
char S[Nmax];
vector < pair < pair < int , int >, int > > V;

void Add ( int x, int y, int z ){
    V.push_back( make_pair( make_pair( x, y ), z ) );
}

struct SuffixArray{

    int LogMax;
    void Build(){

        for ( LogMax = 0; ( 1 << LogMax ) <= N; ++LogMax );

        for ( int i = 1; i <= N; ++i )
            P[0][i] = S[i];

        for ( int i = 1; i <= LogMax; ++i ){
            int len = ( 1 << (i-1) );

            V.clear();
            Add ( -1, -1, -1 );

            for ( int j = 1; j <= N; ++j ){
                int x = P[i-1][j];
                int y = j+len <= N ? P[i-1][j+len] : -1;
                Add ( x, y, j );
            }
            sort ( V.begin(), V.end() );

            int ind = 0;
            for ( int j = 1; j <= N; ++j ){
                if ( V[j].first != V[j-1].first )
                    ind++;
                P[i][V[j].second] = ind;
            }
        }
        for ( int i = 1; i <= N; ++i )
            Poz[P[LogMax][i]] = i;
    }

    int LCP( int x, int y ){
        if ( x == y )
            return N - x + 1;

        int rez = 0;
        for ( int i = LogMax; i >= 0; --i ){
            if ( P[i][x] == P[i][y] ){
                rez += ( 1 << i );
                x += ( 1 << i );
                y += ( 1 << i );
            }
        }
        return rez;
    }
};

SuffixArray SA;

int main(){

    int K;

    fin >> N >> K >> (S+1);

    SA.Build();
    int Sol = -1;

    for ( int i = 1; i <= N-K+1; ++i )
        Sol = max ( Sol, SA.LCP ( Poz[i], Poz[i+K-1] ) );

    fout << Sol;

    return 0;
}