Problem p01756 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i, a) for (auto &i : a)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define RFOR(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; i--)
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define ALL(a) (a).begin(), (a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  EACH(x, vec) is >> x;
  return is;
}
/*
template<class... T>
ostream& operator<<(ostream& os, tuple<T...>& t) {
        for (size_t i = 0; i < tuple_size< tuple<T...> >::value; ++i) {
                if (i) os << " ";
                os << get<0>(t);
        }
        return os;
}
*/
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, vector<vector<T>> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}

struct SAComp {
  const int h, *g;
  SAComp(int h, int *g) : h(h), g(g) {}
  bool operator()(int a, int b) {
    return a == b ? false : g[a] != g[b] ? g[a] < g[b] : g[a + h] < g[b + h];
  }
};
int *buildSA(const char *t, int n) {
  int g[n + 1], b[n + 1], *v = new int[n + 1];
  REP(i, n + 1) v[i] = i, g[i] = t[i];
  b[0] = 0;
  b[n] = 0;

  sort(v, v + n + 1, SAComp(0, g));
  for (int h = 1; b[n] != n; h *= 2) {
    SAComp comp(h, g);
    sort(v, v + n + 1, comp);
    REP(i, n) b[i + 1] = b[i] + comp(v[i], v[i + 1]);
    REP(i, n + 1) g[v[i]] = b[i];
  }
  return v;
}

string S;
int lb(int *sa, string s) {
  int l = 0, r = S.size() + 1;
  REP(t, 20) {
    int m = (l + r) / 2;
    string ss = sa[m] + s.size() <= S.size() ? S.substr(sa[m], s.size())
                                             : S.substr(sa[m]);
    if (ss >= s) {
      r = m;
    } else {
      l = m;
    }
  }
  return r;
}
int ub(int *sa, string s) {
  int l = 0, r = S.size() + 1;
  REP(t, 20) {
    int m = (l + r) / 2;
    string ss = sa[m] + s.size() <= S.size() ? S.substr(sa[m], s.size())
                                             : S.substr(sa[m]);
    if (ss > s) {
      r = m;
    } else {
      l = m;
    }
  }
  return r;
}

int Len = 0;
vector<int> mn, mx;
void init(int n) {
  for (Len = 1; Len < n; Len <<= 1)
    ;
  --Len;
  mn = vector<int>(Len * 2 + 1, inf);
  mx = vector<int>(Len * 2 + 1, -inf);
}
void set_value(int pos, int val) {
  pos += Len;
  mn[pos] = val;
  mx[pos] = val;
  while (1) {
    if (pos == 0)
      break;
    pos = (pos - 1) / 2;
    mn[pos] = min(mn[pos * 2 + 1], mn[pos * 2 + 2]);
    mx[pos] = max(mx[pos * 2 + 1], mx[pos * 2 + 2]);
  }
}
P marge(P p1, P p2) {
  return P(min(p1.first, p2.first), max(p1.second, p2.second));
}
P get_value(int n, int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    // cout << l << " " << r << " " << mn[n] << " " << mx[n] << endl;
    return P(mn[n], mx[n]);
  } else if (r <= L || R <= l) {
    return P(inf, -inf);
  } else {
    int m = (l + r) / 2;
    return marge(get_value(n * 2 + 1, l, m, L, R),
                 get_value(n * 2 + 2, m, r, L, R));
  }
}
P get_value(int l, int r) { return get_value(0, 0, Len + 1, l, r); }

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  int *sa;
  cin >> S;
  int n = S.size();
  sa = buildSA(S.c_str(), n);
  int Q;
  cin >> Q;
  init(n + 1);
  REP(i, n + 1) { set_value(i, sa[i]); }
  // cout << get_value(5, 8).first << endl;
  REP(q, Q) {
    string a, b;
    cin >> a >> b;
    int r1 = inf, r2 = -inf;
    r1 = get_value(lb(sa, a), ub(sa, a)).first;
    r2 = get_value(lb(sa, b), ub(sa, b)).second;
    // FOR(i, lb(sa, a), ub(sa, a)) {
    // 	r1 = min(r1, sa[i]);
    // }
    // FOR(i, lb(sa, b), ub(sa, b)) {
    // 	r2 = max(r2, sa[i]);
    // }
    int ans = 0;
    if (r2 >= r1) {
      ans = r2 - r1 + b.size();
      if (ans < a.size())
        ans = 0;
    }
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i, a) for (auto &i : a)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define RFOR(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; i--)
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define ALL(a) (a).begin(), (a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  EACH(x, vec) is >> x;
  return is;
}
/*
template<class... T>
ostream& operator<<(ostream& os, tuple<T...>& t) {
        for (size_t i = 0; i < tuple_size< tuple<T...> >::value; ++i) {
                if (i) os << " ";
                os << get<0>(t);
        }
        return os;
}
*/
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, vector<vector<T>> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}

struct SAComp {
  const int h, *g;
  SAComp(int h, int *g) : h(h), g(g) {}
  bool operator()(int a, int b) {
    return a == b ? false : g[a] != g[b] ? g[a] < g[b] : g[a + h] < g[b + h];
  }
};
int *buildSA(const char *t, int n) {
  int g[n + 1], b[n + 1], *v = new int[n + 1];
  REP(i, n + 1) v[i] = i, g[i] = t[i];
  b[0] = 0;
  b[n] = 0;

  sort(v, v + n + 1, SAComp(0, g));
  for (int h = 1; b[n] != n; h *= 2) {
    SAComp comp(h, g);
    sort(v, v + n + 1, comp);
    REP(i, n) b[i + 1] = b[i] + comp(v[i], v[i + 1]);
    REP(i, n + 1) g[v[i]] = b[i];
  }
  return v;
}

string S;
int lb(int *sa, string s) {
  int l = 0, r = S.size() + 1;
  while (r - l > 1) {
    int m = (l + r) / 2;
    if (S.substr(sa[m]) >= s) {
      r = m;
    } else {
      l = m;
    }
  }
  return r;
}
int ub(int *sa, string s) {
  int l = 0, r = S.size() + 1;
  while (r - l > 1) {
    int m = (l + r) / 2;
    string ss = sa[m] + s.size() <= S.size() ? S.substr(sa[m], s.size())
                                             : S.substr(sa[m]);
    if (ss > s) {
      r = m;
    } else {
      l = m;
    }
  }
  return r;
}

int Len = 0;
vector<int> mn, mx;
void init(int n) {
  for (Len = 1; Len < n; Len <<= 1)
    ;
  --Len;
  mn = vector<int>(Len * 2 + 1, inf);
  mx = vector<int>(Len * 2 + 1, -inf);
}
void set_value(int pos, int val) {
  pos += Len;
  mn[pos] = val;
  mx[pos] = val;
  while (1) {
    if (pos == 0)
      break;
    pos = (pos - 1) / 2;
    mn[pos] = min(mn[pos * 2 + 1], mn[pos * 2 + 2]);
    mx[pos] = max(mx[pos * 2 + 1], mx[pos * 2 + 2]);
  }
}
P marge(P p1, P p2) {
  return P(min(p1.first, p2.first), max(p1.second, p2.second));
}
P get_value(int n, int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    // cout << l << " " << r << " " << mn[n] << " " << mx[n] << endl;
    return P(mn[n], mx[n]);
  } else if (r <= L || R <= l) {
    return P(inf, -inf);
  } else {
    int m = (l + r) / 2;
    return marge(get_value(n * 2 + 1, l, m, L, R),
                 get_value(n * 2 + 2, m, r, L, R));
  }
}
P get_value(int l, int r) { return get_value(0, 0, Len + 1, l, r); }

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  int *sa;
  cin >> S;
  int n = S.size();
  sa = buildSA(S.c_str(), n);
  int Q;
  cin >> Q;
  init(n + 1);
  REP(i, n + 1) { set_value(i, sa[i]); }
  // cout << get_value(5, 8).first << endl;
  REP(q, Q) {
    string a, b;
    cin >> a >> b;
    int r1 = inf, r2 = -inf;
    r1 = get_value(lb(sa, a), ub(sa, a)).first;
    r2 = get_value(lb(sa, b), ub(sa, b)).second;
    // FOR(i, lb(sa, a), ub(sa, a)) {
    // 	r1 = min(r1, sa[i]);
    // }
    // FOR(i, lb(sa, b), ub(sa, b)) {
    // 	r2 = max(r2, sa[i]);
    // }
    int ans = 0;
    if (r2 >= r1) {
      ans = r2 - r1 + b.size();
      if (ans < a.size())
        ans = 0;
    }
    cout << ans << endl;
  }
}