Cod sursa(job #2021456)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 13 septembrie 2017 18:47:01
Problema Substr Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.53 kb
#include <fstream>
#include <map>
#include <string>
#include <vector>

using namespace std;

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

const int MAX = 2e4;
const int BASE = 227;
map < unsigned long long, int > how_many;

void hash_str(string s, vector < unsigned long long > &H, vector < unsigned long long > &base_pow) {
  for (int i = s.length() - 1; i >= 0; i --) {
    H[i] = H[i + 1] * BASE + (s[i] - '0') * 1ull;
  }

  base_pow[0] = 1;

  for (int i = 1; i < MAX; i ++) {
    base_pow[i] = base_pow[i - 1] * BASE;
  }
}

int nr_of_matches(int len, string s, vector < unsigned long long > &H,
 vector < unsigned long long > &base_pow) {
  
  int cnt = 0;

  how_many.clear();
  for (int i = 0; i <= s.length() - len; i ++) {
    unsigned long long hash_ = H[i] - (base_pow[len] * H[i + len]);
    
    how_many[hash_] ++;
  }

  int ans = 0;
  for (auto x : how_many) {
    ans = max(ans, x.second);
  }

  return ans;
}

void solve(string s, int k, vector < unsigned long long > &H,
 vector < unsigned long long > &base_pow, int &sol) {

  int st = 1;
  int dr = s.length();

  while (st <= dr) {
    int cur_len = (st + dr) >> 1;

    if (nr_of_matches(cur_len, s, H, base_pow) >= k) {
      sol = cur_len;
      st = cur_len + 1;
    }
    else {
      dr = cur_len - 1;
    }
  }
}

int main() {

  int n, k;
  cin >> n >> k;

  string s;
  cin >> s;

  vector < unsigned long long > H(MAX);
  vector < unsigned long long > base_pow(MAX);

  hash_str(s, H, base_pow);

  int sol = 0;

  solve(s, k, H, base_pow, sol);

  cout << sol << '\n';
}