Cod sursa(job #3258857)

Utilizator andreic06Andrei Calota andreic06 Data 23 noiembrie 2024 21:07:40
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.71 kb
#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

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


const int N_MAX = (1 << 16);
int N, K; string input;

const int MOD = 1e9 + 7;
const int BASE = 63; /// 26 + 26 + 10
int h[1 + N_MAX]; int p[N_MAX];

static inline int add (int a, int b) {
    if (a + b >= MOD) return a + b - MOD;
    if (a + b < 0) return a + b + MOD;
    return a + b;
}
static inline int prod (int a, int b) {
    int ret = (int64) a * b % MOD;
    return ret;
}

int decode (char ch) {
   if (isalpha (ch)) {
     if (islower (ch)) return 26 + (ch - 'a' + 1);
     return ch - 'A' + 1;
   }
   return 52 + (ch - '0' + 1);
}

void readInput (void) {
    in >> N >> K; in >> input;
    for (int i = 1; i <= N; i ++)
       h[i] = add (prod (h[i - 1], BASE), decode (input[i - 1]));
    p[0] = 1;
    for (int e = 1; e < N_MAX; e ++) p[e] = prod (p[e - 1], BASE);
}

static inline int getHash (int le, int ri) {
   le ++, ri ++;
   return add (h[ri], -prod (h[le - 1], p[ri - le + 1]));
}

unordered_map<int, int> counter;
bool valid (int len) {
   int ret = 0;
   for (int i = 0; i <= N - len; i ++) {
      int curr_h = getHash (i, i + len - 1);
      counter[curr_h] ++;
      ret = max (ret, counter[curr_h]);
   }
   for (int i = 0; i <= N - len; i ++)
      counter[getHash (i, i + len - 1)] = 0;
   return (ret >= K);
}

void solve (void) {
    int low = 1, high = N;
    int answer = 0;
    while (low <= high) {
       int mid = low + (high - low) / 2;
       if (valid (mid)) answer = mid, low = mid + 1;
       else high = mid - 1;
    }
    out << answer;
}
int main()
{
   readInput ();
   solve ();
    return 0;
}