Problem p02250 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1e9;
const int64_t inf64 = 1e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

using i64 = int64_t;

vector<int> suffix_array(const string &s) {
  const int n = s.size();
  vector<int> rank(n + 1), sa(n + 1), tmp(n + 1);
  for (int i = 0; i <= n; ++i) {
    sa[i] = i;
    rank[i] = i < n ? s[i] : -1;
  }
  for (int k = 1; k <= n; k *= 2) {
    auto compare = [&](int i, int j) {
      if (rank[i] != rank[j])
        return rank[i] < rank[j];
      else {
        int ri = i + k <= n ? rank[i + k] : -1;
        int rj = j + k <= n ? rank[j + k] : -1;
        return ri < rj;
      }
    };
    sort(sa.begin(), sa.end(), compare);
    tmp[sa[0]] = 0;
    for (int i = 1; i <= n; ++i) {
      tmp[sa[i]] = tmp[sa[i - 1]] + (compare(sa[i - 1], sa[i]) ? 1 : 0);
    }
    for (int i = 0; i <= n; ++i) {
      rank[i] = tmp[i];
    }
  }
  return sa;
}

int lower_bound(const string &s, const vector<int> &sa, const string t) {
  int lb = 0, ub = sa.size();
  while (ub - lb > 1) {
    int m = (lb + ub) / 2;
    if (s.substr(sa[m], t.size()) >= t)
      ub = m;
    else
      lb = m;
  }
  return ub;
}

int upper_bound(const string &s, const vector<int> &sa, const string t) {
  int lb = 0, ub = sa.size();
  while (ub - lb > 1) {
    int m = (lb + ub) / 2;
    if (s.substr(sa[m], t.size()) > t)
      ub = m;
    else
      lb = m;
  }
  return ub;
}

void solve() {
  string S;
  int q;
  cin >> S >> q;
  auto sa = suffix_array(S);
  cerr << sa << endl;
  rep(i, 0, q) {
    string T;
    cin >> T;
    if (upper_bound(S, sa, T) - lower_bound(S, sa, T) >= 1)
      cout << 1 << endl;
    else
      cout << 0 << endl;
  }
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  solve();
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1e9;
const int64_t inf64 = 1e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

using i64 = int64_t;

vector<int> suffix_array(const string &s) {
  const int n = s.size();
  vector<int> rank(n + 1), sa(n + 1), tmp(n + 1);
  for (int i = 0; i <= n; ++i) {
    sa[i] = i;
    rank[i] = i < n ? s[i] : -1;
  }
  for (int k = 1; k <= n; k *= 2) {
    auto compare = [&](int i, int j) {
      if (rank[i] != rank[j])
        return rank[i] < rank[j];
      else {
        int ri = i + k <= n ? rank[i + k] : -1;
        int rj = j + k <= n ? rank[j + k] : -1;
        return ri < rj;
      }
    };
    sort(sa.begin(), sa.end(), compare);
    tmp[sa[0]] = 0;
    for (int i = 1; i <= n; ++i) {
      tmp[sa[i]] = tmp[sa[i - 1]] + (compare(sa[i - 1], sa[i]) ? 1 : 0);
    }
    for (int i = 0; i <= n; ++i) {
      rank[i] = tmp[i];
    }
  }
  return sa;
}

int lower_bound(const string &s, const vector<int> &sa, const string t) {
  int lb = 0, ub = sa.size();
  while (ub - lb > 1) {
    int m = (lb + ub) / 2;
    if (s.substr(sa[m], t.size()) >= t)
      ub = m;
    else
      lb = m;
  }
  return ub;
}

int upper_bound(const string &s, const vector<int> &sa, const string t) {
  int lb = 0, ub = sa.size();
  while (ub - lb > 1) {
    int m = (lb + ub) / 2;
    if (s.substr(sa[m], t.size()) > t)
      ub = m;
    else
      lb = m;
  }
  return ub;
}

void solve() {
  string S;
  int q;
  cin >> S >> q;
  auto sa = suffix_array(S);
  rep(i, 0, q) {
    string T;
    cin >> T;
    if (upper_bound(S, sa, T) - lower_bound(S, sa, T) >= 1)
      cout << 1 << endl;
    else
      cout << 0 << endl;
  }
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  solve();
  return 0;
}