Cod sursa(job #2098008)

Utilizator mariusn01Marius Nicoli mariusn01 Data 2 ianuarie 2018 00:12:07
Problema Substr Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <fstream>
#include <iostream>
#include <cstring>
#include <algorithm>



using namespace std;


struct structura {
    int poz;
    int _first;
    int _second;
};

class SuffixArrays {
    int n;
    int *a[30];
    char *s;
    int log;
    structura *L;
    int *P;



public:

    static int cmp(structura a, structura b) {
        if (a._first != b._first)
            return a._first < b._first;
        else
            return a._second < b._second;
    }

    SuffixArrays(char *s) {
        this->s = new char[ strlen(s) + 1 ];
        strcpy(this->s, s);
        n = strlen(s);

        int p = 1;

        for (log = 0; p <= n; log++, p*=2);


        for (int i=0;i<log;i++) {
            a[i] = new int [n];
        }
        L = new structura [n];
        P = new int[n];
    }

    void build () {
        for (int i=0;i<n;i++) {
            L[i].poz = i;
            L[i]._first = s[i];
            L[i]._second = 0;
        }

        for (int lg=0, p = 1; p<=n; lg ++, p*=2) {
            sort(L, L+n, cmp);
            a[lg][ L[0].poz ] = 0;
            for (int i=1;i<n;i++) {
                if ( L[i]._first == L[i-1]._first && L[i]._second == L[i-1]._second ) {
                    a[lg][L[i].poz] = a[lg][L[i-1].poz];
                } else {
                    a[lg][L[i].poz] = 1 + a[lg][L[i-1].poz];
                }
            }
            for (int i=0;i<n;i++) {
                L[i].poz = i;
                L[i]._first = a[lg][i];
                if (i + p < n)
                    L[i]._second = a[lg][ i+p ];
                else
                    L[i]._second = -1;
            }
        }


    }

    int queryPrefix(int dist) {
        for (int i=0;i<n;i++)
            P[ a[log-1][i] ] = i;
        int maxim = 0;
        for (int i=0; i+dist-1 < n; i++) {
            int x = P[i], y = P[i+dist-1];
            int p = 1;
            int lg = 0;
            int sol = 0;
            while (2*p < n) {
                p = 2*p;
                lg++;
            }
            int k;

            if (x == y)
                sol = n - x;
            else
                for (k = lg; k >= 0 && x < n && y < n; --k)
                    if (a[k][x] == a[k][y])
                        x += (1 << k), y += (1 << k), sol += (1 << k);


            maxim = max(maxim, sol);
        }

        return maxim;
    }

    ~SuffixArrays() {
        for (int i=0;i<log;i++)
            delete [] a[i];
        delete L;
        delete P;
    }

} ;

int n, k;
char s[17000];

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

    fin>>n>>k;
    fin>>s;

    SuffixArrays S(s);
    S.build();
    fout<<S.queryPrefix(k);
    return 0;
}