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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_N 400050
int n, k;
int r[MAX_N + 1], r2[MAX_N + 1];
int t[MAX_N + 1];
bool compare_sa(int i, int j) {
  if (r[i] != r[j])
    return r[i] < r[j];
  else {
    int ri = i + k <= n ? r[i + k] : -1;
    int rj = j + k <= n ? r[j + k] : -1;
    return ri < rj;
  }
}
void constract_sa(const string &S, int *sa) {
  n = S.length();
  for (int i = 0; i <= n; i++) {
    sa[i] = i;
    r[i] = i < n ? S[i] : -1;
  }
  for (k = 1; k <= n; k *= 2) {
    sort(sa, sa + n + 1, compare_sa);
    t[sa[0]] = 0;
    for (int i = 0; i <= n; i++) {
      t[sa[i]] = t[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
    }
    for (int i = 0; i <= n; i++) {
      r[i] = t[i];
    }
  }
}
int contains(const string &S, int *sa, string T) {
  int a = 0, b = S.length();
  while (b - a > 1) {
    int c = (a + b) / 2;
    if (S.compare(sa[c], T.length(), T) < 0)
      a = c;
    else
      b = c;
  }
  return S.compare(sa[b], T.length(), T) == 0 ? b : -1;
}
int contains2(const string &S, int *sa, string T) {
  int a = 0, b = S.length() + 1;
  while (b - a > 1) {
    int c = (a + b) / 2;
    if (S.compare(sa[c], T.length(), T) <= 0)
      a = c;
    else
      b = c;
  }
  return S.compare(sa[a], T.length(), T) == 0 ? a : -1;
}

int N, dat[2][2 * MAX_N - 1];
void init(int n_) {
  N = 1;
  while (N < n_)
    N *= 2;
  for (int i = 0; i < 2 * N - 1; i++) {
    dat[0][i] = INT_MAX;
    dat[1][i] = INT_MIN;
  }
}
void update(int k, int a) {
  k += N - 1;
  dat[0][k] = dat[1][k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    dat[0][k] = min(dat[0][k * 2 + 1], dat[0][k * 2 + 2]);
    dat[1][k] = max(dat[1][k * 2 + 1], dat[1][k * 2 + 2]);
  }
}
int query(int a, int b, int k, int l, int r, int f) {
  if (r <= a || b <= l)
    return f ? INT_MIN : INT_MAX;
  if (a <= l && r <= b)
    return dat[f][k];
  else {
    int vl = query(a, b, k * 2 + 1, l, (l + r) / 2, f);
    int vr = query(a, b, k * 2 + 2, (l + r) / 2, r, f);
    return f ? max(vl, vr) : min(vl, vr);
  }
}

int main() {
  string S;
  int sa[MAX_N + 1], m;
  cin >> S >> m;
  constract_sa(S, sa);
  init(n + 1);
  for (int i = 0; i <= (int)S.size(); i++) {
    update(i, sa[i]);
    // cout<<i<<":"<<sa[i]<<endl;
  }
  for (int i = 0; i < m; i++) {
    string x, y;
    cin >> x >> y;
    int lx = contains(S, sa, x), rx = contains2(S, sa, x);
    int ly = contains(S, sa, y), ry = contains2(S, sa, y);
    int ans;
    // cout<<lx<<" "<<rx<<endl<<ly<<"
    // "<<ry<<endl<<query(ly,ry+1,0,0,N,1)<<":"<<query(lx,rx+1,0,0,N,0)<<endl;
    if (lx < 0 || ly < 0)
      ans = 0;
    else {
      int a = query(ly, ry + 1, 0, 0, N, 1), b = query(lx, rx + 1, 0, 0, N, 0);
      if (b + (int)x.size() > a + (int)y.size())
        ans = 0;
      else
        ans = a - b + y.size();
    }
    cout << ans << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_N 200050
int n, k;
int r[MAX_N + 1], r2[MAX_N + 1];
int t[MAX_N + 1];
bool compare_sa(int i, int j) {
  if (r[i] != r[j])
    return r[i] < r[j];
  else {
    int ri = i + k <= n ? r[i + k] : -1;
    int rj = j + k <= n ? r[j + k] : -1;
    return ri < rj;
  }
}
void constract_sa(string S, int *sa) {
  n = S.length();
  for (int i = 0; i <= n; i++) {
    sa[i] = i;
    r[i] = i < n ? S[i] : -1;
  }
  for (k = 1; k <= n; k *= 2) {
    sort(sa, sa + n + 1, compare_sa);
    t[sa[0]] = 0;
    for (int i = 0; i <= n; i++) {
      t[sa[i]] = t[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
    }
    for (int i = 0; i <= n; i++) {
      r[i] = t[i];
    }
  }
}
int contains(string S, int *sa, string T) {
  int a = 0, b = S.length();
  while (b - a > 1) {
    int c = (a + b) / 2;
    if (S.compare(sa[c], T.length(), T) < 0)
      a = c;
    else
      b = c;
  }
  return S.compare(sa[b], T.length(), T) == 0 ? b : -1;
}
int contains2(string S, int *sa, string T) {
  int a = 0, b = S.length() + 1;
  while (b - a > 1) {
    int c = (a + b) / 2;
    if (S.compare(sa[c], T.length(), T) <= 0)
      a = c;
    else
      b = c;
  }
  return S.compare(sa[a], T.length(), T) == 0 ? a : -1;
}

int N, dat[2][2 * MAX_N - 1];
void init(int n_) {
  N = 1;
  while (N < n_)
    N *= 2;
  for (int i = 0; i < 2 * N - 1; i++) {
    dat[0][i] = INT_MAX;
    dat[1][i] = INT_MIN;
  }
}
void update(int k, int a) {
  k += N - 1;
  dat[0][k] = dat[1][k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    dat[0][k] = min(dat[0][k * 2 + 1], dat[0][k * 2 + 2]);
    dat[1][k] = max(dat[1][k * 2 + 1], dat[1][k * 2 + 2]);
  }
}
int query(int a, int b, int k, int l, int r, int f) {
  if (r <= a || b <= l)
    return f ? INT_MIN : INT_MAX;
  if (a <= l && r <= b)
    return dat[f][k];
  else {
    int vl = query(a, b, k * 2 + 1, l, (l + r) / 2, f);
    int vr = query(a, b, k * 2 + 2, (l + r) / 2, r, f);
    return f ? max(vl, vr) : min(vl, vr);
  }
}

int main() {
  string S;
  int sa[MAX_N + 1], m;
  cin >> S >> m;
  constract_sa(S, sa);
  init(S.size() + 1);
  for (int i = 0; i <= (int)S.size(); i++) {
    update(i, sa[i]);
    // cout<<i<<":"<<sa[i]<<endl;
  }
  for (int i = 0; i < m; i++) {
    string x, y;
    cin >> x >> y;
    int lx = contains(S, sa, x), rx = contains2(S, sa, x);
    int ly = contains(S, sa, y), ry = contains2(S, sa, y);
    int ans;
    // cout<<lx<<" "<<rx<<endl<<ly<<"
    // "<<ry<<endl<<query(ly,ry+1,0,0,N,1)<<":"<<query(lx,rx+1,0,0,N,0)<<endl;
    if (lx < 0 || ly < 0)
      ans = 0;
    else {
      int a = query(ly, ry + 1, 0, 0, N, 1), b = query(lx, rx + 1, 0, 0, N, 0);
      if (b + (int)x.size() > a + (int)y.size())
        ans = 0;
      else
        ans = a - b + y.size();
    }
    cout << ans << endl;
  }
  return 0;
}