Cod sursa(job #2728757)

Utilizator PetyAlexandru Peticaru Pety Data 23 martie 2021 17:39:53
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.6 kb
	
#include <bits/stdc++.h>
#define ll long long
#define ld long double
 
using namespace std;
 
const int mod = 1e9 + 9;
 
ifstream fin ("substr.in");
ofstream fout ("substr.out");

int logpow(int a, int b) {
  int ans = 1, d = a;
  while (b) {
    if (b & 1)
      ans = 1ll * ans * d % mod;
    b >>= 1;
    d = 1LL * d * d % mod;
  }
  return ans;
}

int n, k, h[(1 << 14) + 2];
ll pw[(1 << 14) + 2], inv[(1 << 14) + 2], a[(1 << 14) + 2];
string s;

int check (int l) {
  int ans = 0;
  for (int i = 0; i < n - l + 1; i++) {
    ll val = h[i + l - 1] - (i == 0 ? 0 : h[i - 1]) + mod;
    if (val >= mod)
      val -= mod;
    val = 1ll * val * inv[i] % mod;
    //assert(val >= 0 && val < mod);
    a[i] = val;
  }
  sort(a, a + n - l + 1);
  int l1 = 1;
  for (int i = 0; i < n - l; i++)
    if (a[i] == a[i + 1]) {
      l1++;
    }
    else {
      ans = max(ans, l1);
      l1 = 1;
    }
  ans = max(ans, l1);
  return (ans >= k);
}

int main()
{
  srand(time(NULL));
  fin >> n >> k;
  fin >> s;
  ll hash = 0;
  pw[0] = 1;
  int baza = rand() % 1000000;
  for (int i = 1; i <= n; i++) {
    pw[i] = 1ll * pw[i - 1] * baza % mod;
    //assert(pw[i] >= 0 && pw[i] < mod);
  }
  inv[0] = 1;
  for (int i = 1; i <= n; i++)
    inv[i] = logpow(pw[i], mod - 2); 
  for (int i = 0; i < n; i++) {
    hash = hash + 1ll * pw[i] * (ll)(s[i] - 'a') % mod;
    hash %= mod;
    //assert(hash >= 0 && hash < mod);
    h[i] = hash;
  }
  int st = 0, dr = n, ans = 0;
  while (st <= dr) {
    int mij = (st + dr) / 2;
    if (check(mij)) {
      st = mij + 1;
      ans = mij;
    }
    else
      dr = mij - 1;
  }
  fout << ans;
  return 0;
}