Cod sursa(job #2790589)

Utilizator TudolHulubei Tudor Tudol Data 29 octombrie 2021 11:39:18
Problema Substr Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <bits/stdc++.h>
#define P 45999139
using namespace std;
/**
12345678901234534523094766767234897634896767389664

k = 3
abc99abcabcababc
L = 5


0-9
A-Z : 10..35
a-z : 36..61

x = ((x - 1*1000 % P + P) * 10 + 5) % P
x = (2345 - 2*1000) * 10 + 6

h[0] = 7, 14
*/

ifstream fin("substr.in");
ofstream fout("substr.out");
unordered_map<int, int> M;
char text[16400];
int n, k, p62[16385]; /// p62[i] = 52^i

void Make62()
{
    p62[0] = 1;
    for (int i = 1; i <= 16384; i++)
        p62[i] = 1LL * p62[i - 1] * 62 % P;
}

int Cod(char c)
{
    if (c <= '9') return c - '0';
    if (c <= 'Z') return c - 'A' + 10;
    return c - 'a' + 36;
}

/// ret. 1 daca exista o secventa de lungime L care apare
/// in text de cel putin k ori
int Verifica(int L)
{
    M.clear();
    int i, x = 0, e;
    e = p62[L - 1];
    /// formez primul sir de lungime L, modulo P
    for (i = 0; i < L; i++)
        x = (1LL * x * 62 + Cod(text[i])) % P;
    M[x]++;
    ///cout << x << " ";
    for ( ; text[i] != 0; i++)
    {
        x = ((x - 1LL * Cod(text[i-L]) * e % P + P) * 62 + Cod(text[i])) % P;
        M[x]++;
        ///cout << x << " ";
        if (M[x] >= k) return 1;
    }
    return 0;
}

/**
Cauta lungimea maxima L pe care o poate avea
o secventa care apare de cel putin k ori in text
*/
int CautBin()
{
    int st, dr, L, mid;
    st = 1; L = dr = n - k + 1;
    while (st <= dr)
    {
        mid = (st + dr) / 2;
        if (Verifica(mid) == 1)
        {
            L = mid;
            st = mid + 1;
        }
        else dr = mid - 1;
    }
    return L;
}

int main()
{
    fin >> n >> k;
    fin >> text;
    Make62();
    fout << CautBin();
    fout.close();
    ///cout << Verifica(2);
    return 0;
}