Cod sursa(job #1838244)

Utilizator TincaMateiTinca Matei TincaMatei Data 31 decembrie 2016 15:27:45
Problema Substr Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include <cstdio>

const int MAX_N = 16384;
char sir[MAX_N];

const int BAZA = 13513;
const int MOD1 = 561307;
const int MOD2 = 666013;
const int MOD = (1 << 16);

int last[MOD], next[MAX_N], m1[MAX_N], m2[MAX_N], fr[MAX_N];
int pr1[1+MAX_N], pr2[1+MAX_N];

int top;

int add(int a, int b) {
  int h = (long long)a * b & (MOD - 1);
  int i = last[h];
  while(i != 0 && !(m1[i] == a && m2[i] == b))
    i = next[i];
  if(i != 0) {
    fr[i]++;
    return fr[i];
  }
  else {
    next[top] = last[h];
    m1[top] = a;
    m2[top] = b;
    last[h] = top;
    fr[top] = 1;
    ++top;
  }
  return fr[top - 1];
}

bool check(int n, int k, int win) {
  int a, b;
  int p1, p2;
  bool ok = false;
  p1 = p2 = 1;
  a = b = 0;
  for(int i = 0; i < win - 1; ++i) {
    a = ((long long)a * BAZA + sir[i]) % MOD1;
    b = ((long long)b * BAZA + sir[i]) % MOD2;
    p1 = (long long)p1 * BAZA % MOD1;
    p2 = (long long)p2 * BAZA % MOD2;
  }
  for(int i = win - 1; i < n; ++i) {
    a = ((long long)a * BAZA + sir[i]) % MOD1;
    b = ((long long)b * BAZA + sir[i]) % MOD2;
    if(add(a, b) >= k)
      ok = true;
    a = ((a - sir[i - win + 1] * p1) % MOD1 + MOD1) % MOD1;
    b = ((b - sir[i - win + 1] * p2) % MOD2 + MOD2) % MOD2;
  }
  return ok;
}

int main() {
  int n, k;
  FILE *fin = fopen("substr.in", "r");
  fscanf(fin, "%d%d\n", &n, &k);
  for(int i = 0; i < n; ++i)
    sir[i] = fgetc(fin);
  fclose(fin);

  int st, dr, mid;
  st = 0;
  dr = n + 1;
  while(dr - st > 1) {
    mid = (st + dr) / 2;
    if(check(n, k, mid))
      st = mid;
    else
      dr = mid;
  }
  FILE *fout = fopen("substr.out", "w");
  fprintf(fout, "%d", st);
  fclose(fout);
  return 0;
}