Cod sursa(job #2774660)

Utilizator sergioneUngureanu Sergiu sergione Data 12 septembrie 2021 11:01:22
Problema Substr Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <fstream>
#include <map>

using namespace std;

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

const int mod = 2e9 + 11;
const int sigma = 62;

int n, k;

string s;

int ind[128];

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;
}

int ridLog(int n, int p)
{
    int ans = 1;

    while (p)
    {
        if (p % 2)
            ans = (1LL * ans * n) % mod;

        n = (1LL * n * n) % mod;
        p /= 2;
    }

    return ans;
}

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

    int h = 0, p = 1;

    for (int i = 0 ; i < value; i++)
    {
        h = (1LL * h * sigma + ind[s[i]]) % mod;

        if (i > 0)
            p = (1LL * p * sigma) % mod;
    }

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

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

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

    return false;
}

int main()
{
    init();

    f >> n >> k >> s;

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

    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;
}