Cod sursa(job #1520805)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 9 noiembrie 2015 15:23:42
Problema Substr Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.78 kb
#include <fstream>

using namespace std;

typedef unsigned long long u64;

const int MAX_N = 16384;
const int BASE = 37;
const int MOD = 196613;
const int NIL = -1;

struct cell {
    int H;
    int contor, next;
};

cell l[MAX_N];
int start[MOD];
int ptr;

int H[MAX_N];
int pow[MAX_N];

int hashAdd(int KEY) {
    while (KEY < 0) {
        KEY += MOD;
    }
    int i = start[KEY % MOD];
    while ((i != NIL) && (l[i].H != KEY)) {
        i = l[i].next;
    }
    if (i != NIL) {
        return ++l[i].contor;
    } else {
        l[ptr] = { KEY, 1, start[KEY % MOD] };
        start[KEY % MOD] = ptr++;
        return 1;
    }
}

int main(void) {
    ifstream in("substr.in");
    ofstream out("substr.out");
    char s[MAX_N + 1];
    int n, k;

    in >> n >> k >> s;

    H[0] = s[0];
    pow[0] = 1;
    for (int i = 1; i < n; i++) {
        H[i] = (1ULL * H[i - 1] * BASE + s[i]) % MOD;
        pow[i] = (1ULL * pow[i - 1] * BASE) % MOD;
    }

    auto binSearch = [&] () -> int {
        auto go = [&] (const int &LEN) -> int {
            // goleste hash-ul
            for (int i = 0; i < MOD; i++) {
                start[i] = NIL;
            }
            ptr = 0;
            int q = 0;
            for (int i = 0; i + LEN <= n; i++) {
                q = max(q, hashAdd(H[i + LEN - 1] - (i ? H[i - 1] * pow[LEN] : 0)));
            }
            return q;
        };
        int step = n, pos = 0;
        while (step & (step - 1)) {
            step -= (step & -step);
        }
        for (; step; step >>= 1) {
            if ((pos + step < n) && go(pos + step) >= k) {
                pos += step;
            }
        }
        return pos;
    };

    out << binSearch() << '\n';
    out.close();
    return 0;
}