Cod sursa(job #3227191)

Utilizator Nasa1004Ema Nicole Gheorghe Nasa1004 Data 26 aprilie 2024 22:03:11
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.23 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;
        }
    }

    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()]++;
        ans = max(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) { ///cautam binar LEN-ul, nu de unde incepe
        mid = (st + dr) / 2;
        if(validLen(mid) >= k) ///dc e valid deja
            st = mid; ///incercam SI mai mare
        else
            dr = mid;
    }
    cout << st;
}