Cod sursa(job #989736)

Utilizator florin.elfusFlorin Elfus florin.elfus Data 26 august 2013 13:25:28
Problema Substr Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>

#define REP(i, a, b) for(int i = a; i <= b; ++i)
#define REPD(i, a, b) for(int i = a; i >= b; --i)
#define FOR(i, n) REP(i, 1, n)
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
#define chmax(a, b) a = max(a, b)
#define chmin(a, b) a = min(a, b)
#define read(n) int (n); scanf("%d", &(n))
#define read2(n, m) int (n), (m); scanf("%d %d", &(n), &(m))
#define read3(n, m, k) int (n), (m), (k); scanf("%d %d %d", &(n), &(m), &(k))
#define ll long long
#define x first
#define y second
#define mp make_pair
#define pb push_back

using namespace std;

char x[17000];
int idx[17000], SA[15][17000];
ll key[17000];

struct comp {
    bool operator () (int i, int j) {
        return key[i] < key[j];
    }
};

void suffixArrays(int n) {
    FOR(i, n)
        SA[0][i] = x[i] - '0' + 1;
    for (int pw = 1; (1 << pw) <= 2 * n; ++pw) {
        FOR(i, n) {
            key[i] = 1LL * SA[pw - 1][i] * max(n, 1000);
            if (i + (1 << (pw - 1)) <= n)
                key[i] += SA[pw - 1][i + (1 << (pw - 1))];
            idx[i] = i;
        }
        sort(idx + 1, idx + n + 1, comp());
        int cur = 0;
        FOR(i, n)
            if (i > 1 && key[idx[i]] == key[idx[i - 1]])
                SA[pw][idx[i]] = cur;
            else
                SA[pw][idx[i]] = ++cur;
    }
}

int lcp(int i, int j, int n) {
    int lim = min(n - i + 1, n - j + 1), pw;
    for (pw = 0; (1 << pw) <= lim; ++pw); --pw;
    int res = 0;
    for (; pw >= 0; --pw)
        if (SA[pw][i] == SA[pw][j]) {
            i += (1 << pw); j += (1 << pw);
            res += (1 << pw);
        }
    return res;
}

int main() {
    freopen("substr.in", "r", stdin);
    freopen("substr.out", "w", stdout);

    read2(n, m); scanf("\n");
    gets(x + 1);

    suffixArrays(n);
    int pw;
    for (pw = 0; (1 << pw) <= n; ++pw);
    FOR(i, n)
        idx[SA[pw][i]] = i;
    int sol = 0;
    FOR(i, n - m + 1)
        chmax(sol, lcp(idx[i], idx[i + m - 1], n));
    printf("%d", sol);
    return 0;
}