Cod sursa(job #3193005)

Utilizator Nasa1004Ema Nicole Gheorghe Nasa1004 Data 13 ianuarie 2024 18:55:53
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <fstream>
#include <string>
#include <climits>
#include <unordered_map>

using namespace std;

string str;

template <uint64_t MOD> ///orice facem e mod MOD cand folosim asta
uint64_t logexp(uint64_t base, uint64_t exp) { ///exp rapida
    uint64_t ans = 1;
    for(int k = 1; k <= exp; k <<= 1)
    {
        if((exp & k))
            ans = (ans * base) % MOD;
        base = (base * base) % MOD;
    }
    return ans;
}
template <uint64_t MOD>
uint64_t invmod(uint64_t num) { ///invers modular
    return logexp <MOD>(num, MOD - 2);
}

template <uint64_t B, uint64_t MOD> ///B-ul pt formula si MOD-ul
class roll_hash {
private:
    int x, y; ///2 nr care sunt inceputul si sfarsitul secv?
    uint64_t hash = 0; ///hash-ul in sine
public:
    roll_hash(int set_x, int set_y) { ///in roll_hash fm
        x = set_x;
        y = set_y;
        for(int i = x; i < y; i++) {
            hash += (int)str[i] * logexp <MOD> (B, i - x); /// * B^(i - x)
            hash %= MOD;
        }
        //cout << "hash-ul ii " << hash << '\n';
    }

    uint64_t get_hash() {
        return hash;
    }

    void addx() { ///scoatem un nr din st
        hash = (hash - (int)str[x]) * invmod <MOD> (B);
        hash %= MOD;
        x++;
    }
    void addy() {
        hash += (int)str[y] * logexp <MOD> (B, y - x);
        hash %= MOD;
        y++;
    }
};

int validLen(int len) {
    unordered_map < int, int > umap;
    roll_hash <127, 1000000007> check(0, len); ///de la 0 la len, primul hash init
    int ans = -1;
    for (int i = len; i <= str.size(); i++) {
        //cout << check.get_hash() << '\n';
        umap[check.get_hash()]++;
        if (ans < umap[check.get_hash()]) {
            ans = umap[check.get_hash()];
        }
        check.addx(); ///trecem la urm secv
        check.addy();
    }
    //cout << "ans de " << len << " ii " << ans << '\n';
    return ans;
}

int main() {
    ifstream cin("substr.in");
    ofstream cout("substr.out");
    int n, k;
    cin >> n >> k >> str;

    int st = 1, dr = n + 1, mid;
    while(1 < dr - st) {
        mid = (st + dr) / 2;
        //cout << st << " " << mid << " " << dr << '\n';
        if(validLen(mid) >= k) ///dc e valid deja
            st = mid; ///incercam SI mai mare
        else
            dr = mid;
    }
    cout << st;
}