Problem p03904 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
const int MAXN = 400005;

namespace sfxarray {
int ord[MAXN], nord[MAXN], cnt[MAXN], aux[MAXN];
void solve(int n, char *str, int *sfx, int *rev, int *lcp) {
  int p = 1;
  memset(ord, 0, sizeof(ord));
  for (int i = 0; i < n; i++) {
    sfx[i] = i;
    ord[i] = str[i];
  }
  ord[n] = 255;
  int pnt = 1;
  while (1) {
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < n; i++) {
      cnt[ord[min(i + p, n)]]++;
    }
    for (int i = 1; i <= n || i <= 255; i++) {
      cnt[i] += cnt[i - 1];
    }
    for (int i = n - 1; i >= 0; i--) {
      aux[--cnt[ord[min(i + p, n)]]] = i;
    }
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < n; i++) {
      cnt[ord[i]]++;
    }
    for (int i = 1; i <= n || i <= 255; i++) {
      cnt[i] += cnt[i - 1];
    }
    for (int i = n - 1; i >= 0; i--) {
      sfx[--cnt[ord[aux[i]]]] = aux[i];
    }
    if (pnt == n)
      break;
    pnt = 1;
    nord[sfx[0]] = 1;
    for (int i = 1; i < n; i++) {
      if (ord[sfx[i - 1]] != ord[sfx[i]] ||
          ord[sfx[i - 1] + p] != ord[sfx[i] + p]) {
        pnt++;
      }
      nord[sfx[i]] = pnt;
    }
    memcpy(ord, nord, sizeof(int) * n);
    p *= 2;
  }
  for (int i = 0; i < n; i++) {
    rev[sfx[i]] = i;
  }
  int h = 0;
  for (int i = 0; i < n; i++) {
    if (rev[i]) {
      int prv = sfx[rev[i] - 1];
      while (str[prv + h] == str[i + h])
        h++;
      lcp[rev[i]] = h;
    }
    h = max(h - 1, 0);
  }
}
} // namespace sfxarray

int n, k;
char str[MAXN];
int sfx[MAXN], rev[MAXN], lcp[MAXN];
int dp[MAXN];
priority_queue<pi, vector<pi>, greater<pi>> pq;

int trial(int v) {
  while (!pq.empty())
    pq.pop();
  int l = (n + k - 1) / k;
  pq.push(pi(0, 0));
  for (int i = 1; i <= n; i++) {
    while (!pq.empty() && pq.top().second < i - l)
      pq.pop();
    if (!pq.empty() && pq.top().second == i - l && rev[i - l] > v)
      pq.pop();
    dp[i] = (pq.empty() ? 1e9 : pq.top().first) + 1;
    pq.push(pi(dp[i], i));
  }
  return dp[n];
}

int main() {
  scanf("%d %s", &k, str);
  k++;
  n = strlen(str);
  sfxarray::solve(n, str, sfx, rev, lcp);
  int s = 0, e = n - 1;
  while (s != e) {
    int m = (s + e) / 2;
    if (trial(m) <= k)
      e = m;
    else
      s = m + 1;
  }
  for (int j = sfx[s]; j < sfx[s] + (n + k - 1) / k; j++)
    printf("%c", str[j]);
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
const int MAXN = 400005;

namespace sfxarray {
int ord[MAXN], nord[MAXN], cnt[MAXN], aux[MAXN];
void solve(int n, char *str, int *sfx, int *rev, int *lcp) {
  int p = 1;
  memset(ord, 0, sizeof(ord));
  for (int i = 0; i < n; i++) {
    sfx[i] = i;
    ord[i] = str[i];
  }
  int pnt = 1;
  while (1) {
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < n; i++) {
      cnt[ord[min(i + p, n)]]++;
    }
    for (int i = 1; i <= n || i <= 255; i++) {
      cnt[i] += cnt[i - 1];
    }
    for (int i = n - 1; i >= 0; i--) {
      aux[--cnt[ord[min(i + p, n)]]] = i;
    }
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < n; i++) {
      cnt[ord[i]]++;
    }
    for (int i = 1; i <= n || i <= 255; i++) {
      cnt[i] += cnt[i - 1];
    }
    for (int i = n - 1; i >= 0; i--) {
      sfx[--cnt[ord[aux[i]]]] = aux[i];
    }
    if (pnt == n)
      break;
    pnt = 1;
    nord[sfx[0]] = 1;
    for (int i = 1; i < n; i++) {
      if (ord[sfx[i - 1]] != ord[sfx[i]] ||
          ord[sfx[i - 1] + p] != ord[sfx[i] + p]) {
        pnt++;
      }
      nord[sfx[i]] = pnt;
    }
    memcpy(ord, nord, sizeof(int) * n);
    p *= 2;
  }
  for (int i = 0; i < n; i++) {
    rev[sfx[i]] = i;
  }
  int h = 0;
  for (int i = 0; i < n; i++) {
    if (rev[i]) {
      int prv = sfx[rev[i] - 1];
      while (str[prv + h] == str[i + h])
        h++;
      lcp[rev[i]] = h;
    }
    h = max(h - 1, 0);
  }
}
} // namespace sfxarray

int n, k;
char str[MAXN];
int sfx[MAXN], rev[MAXN], lcp[MAXN];
int dp[MAXN];
priority_queue<pi, vector<pi>, greater<pi>> pq;

int trial(int v) {
  while (!pq.empty())
    pq.pop();
  int l = (n + k - 1) / k;
  pq.push(pi(0, 0));
  for (int i = 1; i <= n; i++) {
    while (!pq.empty() && pq.top().second < i - l)
      pq.pop();
    if (!pq.empty() && pq.top().second == i - l && rev[i - l] > v)
      pq.pop();
    dp[i] = (pq.empty() ? 1e9 : pq.top().first) + 1;
    pq.push(pi(dp[i], i));
  }
  return dp[n];
}

int main() {
  scanf("%d %s", &k, str);
  k++;
  n = strlen(str);
  sfxarray::solve(n, str, sfx, rev, lcp);
  int s = 0, e = n - 1;
  while (s != e) {
    int m = (s + e) / 2;
    if (trial(m) <= k)
      e = m;
    else
      s = m + 1;
  }
  for (int j = sfx[s]; j < sfx[s] + (n + k - 1) / k; j++)
    printf("%c", str[j]);
}