Cod sursa(job #2734043)

Utilizator BAlexandruBorgovan Alexandru BAlexandru Data 31 martie 2021 12:06:29
Problema Potrivirea sirurilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <fstream>
#include <unordered_map>

using namespace std;

ifstream f("substr.in");
ofstream g("substr.out");

const long long mod = 999999999989;
const long long base = 211;

int n, k;

string s;

long long ind[128];

long long H[16400], P[16400];

void init()
{
    int p = 0;

    for (char c = 'a'; c <= 'z'; c++, p++)
        ind[c] = p;

    for (char c = 'A'; c <= 'Z'; c++, p++)
        ind[c] = p;

    for (char c = '0'; c <= '9'; c++, p++)
        ind[c] = p;

    for (int i = 0; i < s.size(); i++)
    {
        H[i] = (H[i - 1] * base + ind[s[i]]) % mod;

        if (i == 0)
            P[i] = 1;
        else
            P[i] = (P[i - 1] * base) % mod;
    }
}

bool ok(int value)
{
    unordered_map < long long, int > cnt;

    long long h = H[value - 1], p = P[value - 1];

    cnt[h]++;
    if (cnt[h] >= k)
        return true;

    for (int i = value; i < s.size(); i++)
    {
        h = (h + mod - (p * ind[s[i - value]]) % mod) % mod;
        h = (h * base + ind[s[i]]);

        cnt[h]++;
        if (cnt[h] >= k)
            return true;
    }

    return false;
}

int main()
{
    f >> n >> k >> s;

    init();

    int ans = 0;
    int left = 1, right = s.size() / k;

    while (left <= right)
    {
        int mid = (left + right) / 2;

        if (ok(mid))
        {
            ans = mid;
            left = mid + 1;
        }
        else
            right = mid - 1;
    }

    g << ans << "\n";

    return 0;
}