Cod sursa(job #887044)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 23 februarie 2013 15:08:40
Problema Substr Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <fstream>
#include <algorithm>

#define MAX 16400
#define LMAX 15
#define poz second
#define val first

using namespace std;

int N, K, cnt, step;
int Sorted[LMAX][MAX];
pair< pair<int, int>, int > V[MAX];
pair< int, int > SArray[MAX];
string S;


void citire() {
    ifstream in("substr.in");
    in>>N>>K; in.get();
    getline(in, S);
    S = " " + S;
    in.close();
}

inline int getNr(const char &X) {
    if(isdigit(X)) return X - '0';
    if(isupper(X)) return X - 'A' + 10;
    return X - 'a' + 37;
}

inline int LCP(int X, int Y)
{
    if(X == Y) return N - X + 1;
    int rez = 0;
    for(int cnt = step - 1; cnt >= 0 && X <= N && Y <= N; cnt--) {
        if(Sorted[cnt][X] == Sorted[cnt][Y]) {
            X += (1 << cnt), Y += (1 << cnt), rez += (1 << cnt);
        }
    }
    return rez;
}

void preprocess() {
    for(int i = 1; i <= N; i++)
        Sorted[0][i] = getNr(S[i]);
    for(step = 1, cnt = 1; (cnt >> 1) <= N; step++, cnt <<= 1) {
        for(int i = 1; i <= N; i++) {
            V[i].val.first = Sorted[step - 1][i];
            V[i].val.second = (i + cnt <= N ? Sorted[step - 1][i + cnt] : -1);
            V[i].poz = i;
        }
        sort(V + 1, V + N + 1); int X;
        for(int i = 1; i <= N; i++) {
            if(i == 1) X = 1;
            else if(V[i].val.first != V[i - 1].val.first || V[i].val.second != V[i - 1].val.second) X++;
            Sorted[step][V[i].poz] = X;
        }
    } step--;
    for(int i = 1; i <= N; i++) {
        SArray[i].first = Sorted[step][i];
        SArray[i].second = i;
    } sort(SArray + 1, SArray + N);
}

int main() {
    citire();
    preprocess();
    int rez = 0;
    for(int i = 1; i <= N - K + 1; i++)
        rez = max(rez, LCP(SArray[i].second, SArray[i + K - 1].second));
    ofstream out("substr.out"); out<<rez<<"\n"; out.close();
}