Problem p02589 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
typedef long long ll;
typedef long double ld;

int get_lcp(string a, string b) {
  int com = 0;
  while (com < (int)a.size() && com < (int)b.size() && a[com] == b[com]) {
    com++;
  }
  return com;
}

const int N = (int)2e5 + 7;
int n;
int lcp[N];
int lim[N], bg[N];
int t[4 * N];
int f[N][26];
string a[N];
int mn[26][4 * N];
int mx[26][4 * N];

void build(int v, int tl, int tr) {
  if (tl == tr) {
    for (int x = 0; x < 26; x++) {
      mn[x][v] = mx[x][v] = f[tl][x];
    }
    t[v] = lcp[tl];
  } else {
    int tm = (tl + tr) / 2;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    t[v] = min(t[2 * v], t[2 * v + 1]);
    for (int x = 0; x < 26; x++) {
      mn[x][v] = min(mn[x][2 * v], mn[x][2 * v + 1]);
      mx[x][v] = max(mx[x][2 * v], mx[x][2 * v + 1]);
    }
  }
}

int get(int v, int tl, int tr, int l, int r) {
  if (tr < l || r < tl) {
    return (int)1e9;
  }
  if (l <= tl && tr <= r) {
    return t[v];
  }
  int tm = (tl + tr) / 2;
  return min(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm + 1, tr, l, r));
}

void build() { build(1, 1, n); }

int get(int i, int j) {
  if (i == j) {
    cout << "why equal?\\n";
    exit(0);
  }
  if (i > j) {
    swap(i, j);
  }
  return get(1, 1, n, i, j - 1);
}

int calc(int v, int tl, int tr, int l, int r, int x, int need) {
  if (tr < l || r < tl) {
    return 0;
  }
  if (l <= tl && tr <= r) {
    if (mn[x][v] >= need) {
      return tr - tl + 1;
    }
    if (mx[x][v] < need) {
      return 0;
    }
  }
  int tm = (tl + tr) / 2;
  return calc(2 * v, tl, tm, l, r, x, need) +
         calc(2 * v + 1, tm + 1, tr, l, r, x, need);
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    reverse(a[i].begin(), a[i].end());
  }
  sort(a + 1, a + n + 1);
  for (int i = 1; i < n; i++) {
    lcp[i] = get_lcp(a[i], a[i + 1]);
  }
  for (int i = 1; i <= n; i++) {
    for (auto &ch : a[i]) {
      f[i][ch - 'a']++;
    }
  }
  build();
  for (int i = 1; i <= n; i++) {
    int len = (int)a[i].size();
    int pos = i, lo = i + 1, hi = n;
    while (lo <= hi) {
      int mid = (lo + hi) / 2;
      if (get(i, mid) >= len - 1) {
        pos = mid;
        lo = mid + 1;
      } else {
        hi = mid - 1;
      }
    }
    lim[i] = pos;
    pos = i;
    lo = 1;
    hi = i - 1;
    while (lo <= hi) {
      int mid = (lo + hi) / 2;
      if (get(mid, i) >= len - 1) {
        pos = mid;
        hi = mid - 1;
      } else {
        lo = mid + 1;
      }
    }
    bg[i] = pos;
  }
  ll sol = 0;
  for (int i = 1; i <= n; i++) {
    int x = a[i].back() - 'a', need = f[i][x];
    int now = calc(1, 1, n, bg[i], lim[i], x, need);
    sol += now - 1;
  }
  cout << sol << "\\n";
  return 0;
}


Error: -11

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
typedef long long ll;
typedef long double ld;

int get_lcp(string a, string b) {
  int com = 0;
  while (com < (int)a.size() && com < (int)b.size() && a[com] == b[com]) {
    com++;
  }
  return com;
}

const int N = (int)2e5 + 7;
int n;
int lcp[N];
int lim[N];
int t[4 * N];
int f[N][26];
string a[N];

void build(int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = lcp[tl];
  } else {
    int tm = (tl + tr) / 2;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    t[v] = min(t[2 * v], t[2 * v + 1]);
  }
}

int get(int v, int tl, int tr, int l, int r) {
  if (tr < l || r < tl) {
    return (int)1e9;
  }
  if (l <= tl && tr <= r) {
    return t[v];
  }
  int tm = (tl + tr) / 2;
  return min(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm + 1, tr, l, r));
}

void build() { build(1, 1, n - 1); }

int get(int i, int j) {
  if (i == j) {
    cout << "why equal?\\n";
    exit(0);
  }
  if (i > j) {
    swap(i, j);
  }
  return get(1, 1, n - 1, i, j - 1);
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  freopen("input", "r", stdin);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    reverse(a[i].begin(), a[i].end());
  }
  sort(a + 1, a + n + 1);
  for (int i = 1; i < n; i++) {
    lcp[i] = get_lcp(a[i], a[i + 1]);
  }
  build();
  for (int i = 1; i <= n; i++) {
    for (auto &ch : a[i]) {
      f[i][ch - 'a']++;
    }
  }
  for (int i = 1; i <= n; i++) {
    int len = (int)a[i].size();
    int pos = i, lo = i + 1, hi = n;
    while (lo <= hi) {
      int mid = (lo + hi) / 2;
      if (get(i, mid) >= len - 1) {
        pos = mid;
        lo = mid + 1;
      } else {
        hi = mid - 1;
      }
    }
    lim[i] = pos;
  }
  ll sol = 0;
  for (int i = 1; i <= n; i++) {
    int x = a[i].back() - 'a', need = f[i][x];
    for (int j = i + 1; j <= lim[i]; j++) {
      if (f[j][x] >= need) {
        sol++;
      }
    }
  }
  cout << sol << "\\n";
  return 0;
}