Cod sursa(job #1746190)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 22 august 2016 19:23:17
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include<fstream>
#include<string>
#include<algorithm>

using namespace std;

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

const int nmax = 16384;
const int logmax = 14;

int n, k;
int p[logmax + 1][nmax + 1];
string s;

struct str{
    int ind, x, y;

    str() {}
    str( int _ind, int _x, int _y ) { ind = _ind, x = _x, y = _y; }

    inline bool operator < (const str &a) const { return (x != a.x) ? (x < a.x) : (y < a.y); }
    inline bool operator == (const str &a) const { return (x == a.x) && (y == a.y); }
} v[nmax + 1];

inline int max2( int x, int y ) {
    return (x < y ? y : x);
}
inline int val( char x ) {
    if (x >= '0' && x <= '9') {
        return x - '0';
    } else if ( x >= 'a' && x <= 'z' ) {
        return 10 + x - 'a';
    } else return 10 + 26 + x - 'A';
}
void suffix_array() {
    for (int i = 1; i <= n; ++ i) {
        p[ 0 ][ i ] = val(s[i - 1]);
    }

    for (int i = 1; i <= logmax; ++ i) {
        for (int j = 1; j <= n; ++ j) {
            int x = 0;
            if ( j + (1 << (i - 1)) <= n ) {
                x = p[i - 1][j + (1 << (i - 1))];
            }
            v[ j ] = str( j, p[i - 1][ j ], x );
        }
        sort(v + 1, v + n + 1);

        int nr = 1;
        for (int j = 1; j <= n;) {
            int ind = j; str aux = v[ j ];
            while (ind <= n && aux == v[ ind ]) {
                p[ i ][ v[ ind ].ind ] = nr;
                ++ ind;
            }

            ++ nr;
            j = ind;
        }
    }
}
int lcp( int x, int y ) {
    int ans = 0;
    for (int i = logmax; i >= 0; -- i) {
        if (x + (1 << i) - 1 <= n && y + (1 << i) - 1 <= n && p[ i ][ x ] == p[ i ][ y ]) {
            ans += (1 << i);
            x += (1 << i);
            y += (1 << i);
        }
    }
    return ans;
}
int main() {
    fin >> n >> k >> s;
    suffix_array();

    int ans = 0;
    for (int i = 1; i <= n - k + 1; ++ i) {
        ans = max2(ans, lcp(v[ i ].ind, v[i + k - 1].ind));
    }

    fout << ans << "\n";

    fin.close();
    fout.close();
    return 0;
}