Cod sursa(job #2060617)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 8 noiembrie 2017 15:50:56
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAX_N = 16384;
const int MAX_LOG = 15;

char s[MAX_N + 5];
int v[MAX_LOG + 5][2 * MAX_N + 5];
int suffix[MAX_N + 5];

struct Norm {
  int val1, val2, poz;

  bool operator < (const Norm& other) const {
    if (other.val1 == this->val1) {
      if (other.val2 == this->val2)
        return this->poz > other.poz;
      return this->val2 < other.val2;
    }
    return this->val1 < other.val1;
  }
}aux[MAX_N + 5];

int lcp(int x, int y, int n, int last) {
  int ans = 0;
  for (int i = last; i >= 0; --i) {
    if (x <= n && y <= n && v[i][x] == v[i][y]) {
      x += (1 << i);
      y += (1 << i);
      ans += (1 << i);
    }
  }

  return ans;
}

int main() {
  freopen("substr.in", "r", stdin);
  freopen("substr.out", "w", stdout);

  int n, p;
  scanf("%d%d ", &n, &p);

  if (p == 1) {
    printf("%d\n", n);
    return 0;
  }

  gets(s + 1);
  s[n + 1] = -1;
  for (int i = 1; i <= n; ++i)
    aux[i] = {s[i], 0, i};

  sort(aux + 1, aux + n + 1);

  int k = 1;
  for (int i = 1; i <= n; ++i) {
    v[0][aux[i].poz] = k;
    i++;
    while (i <= n && aux[i].val1 == aux[i - 1].val1 && aux[i].val2 == aux[i - 1].val2) {
      v[0][aux[i].poz] = k;
      i++;
    }
    i--;
    k++;
  }

  int length = 1, last = 1;
  for (int i = 1; length < n; i++) {
    for (int j = 1; j <= n; ++j)
      aux[j] = {v[i - 1][j], v[i - 1][j + length], j};

    sort(aux + 1, aux + n + 1);

    k = 1;
    for (int j = 1; j <= n; ++j) {
      v[i][aux[j].poz] = k;
      j++;
      while (j <= n && aux[j].val1 == aux[j - 1].val1 && aux[j].val2 == aux[j - 1].val2) {
        v[i][aux[j].poz] = k;
        j++;
      }
      j--;
      k++;
    }
    length *= 2;
    last = i;
  }

  for (int i = 1; i <= n; ++i)
    aux[i] = {v[last][i], 0, i};

  sort(aux + 1, aux + n + 1);

  for (int i = 1; i <= n; ++i)
    suffix[i] = aux[i].poz;

  int ans = 0;
  for (int i = 1; i <= n - p + 1; ++i)
    ans = max(ans, lcp(suffix[i], suffix[i + p - 1], n, last));
  printf("%d\n", ans);

  return 0;
}