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

/*
 * Multiple string matching (suffix array)
 * O(T log T + \\sum (P_i log T))
 *
 * Construction: reduce to sorting the cyclic shifts of A||'$'
 */

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

constexpr int kAlphabetSize = 37;

int ValueOf(char ch) {
  if (ch == '$')
    return 0;
  if ('0' <= ch && ch <= '9')
    return 1 + ch - '0';
  if ('a' <= ch && ch <= 'z')
    return 11 + ch - 'a';
  cout << "Unexpected character!" << endl;
  exit(1);
  return -1;
}

vector<int> SortCyclicShifts(string &A) {
  // Approach: sort cyclic substrings of length 1, 2, 4, ..., 2^(\\ceil \\lg n)
  int n = A.size();

  // After step k,
  // p[i] stores the index (in A) of the ith-smallest (starting
  // from 0) cyclic substring of A of length 2^k;
  // c[i] stores the equivalence class (dense, starting from 0, in increasing
  // sorted value order) of the length-2^k substring starting at A[i]
  //
  // psecond and cnext are temporary arrays used to populate p and c each step
  // count is an auxiliary array used for bucket sort
  vector<int> p(n), c(n), psecond(n), cnext(n), count(max(n, kAlphabetSize));

  // Step 1: sort cyclic substrings of length 1
  for (int i = 0; i < n; ++i)
    ++count[ValueOf(A[i])];
  for (int i = 1; i < count.size(); ++i)
    count[i] += count[i - 1];
  for (int i = n - 1; i >= 0; --i)
    p[--count[ValueOf(A[i])]] = i;

  int num_classes = 1;
  for (int i = 1; i < n; ++i) {
    if (A[p[i]] != A[p[i - 1]]) {
      c[p[i]] = num_classes;
      ++num_classes;
    } else {
      c[p[i]] = c[p[i - 1]];
    }
  }

  // Step 2: for each k=1,...,ceil(log2(n)), use
  // the result of sorting the cyclic substrings of length 2^{k-1} to
  // sort the cyclic substrings of length 2^k
  for (int h /* k-1 */ = 0; (1 << h) < n; ++h) {
    // First, sort the cyclic substrings of length 2^k by their second halves;
    // to do this, directly apply the fact that the second half of a length
    // 2^k substring starting at index i is the length-2^{k-1} substring
    // starting at index (i+2^{k-1})
    for (int i = 0; i < n; ++i) {
      psecond[i] = p[i] - (1 << h);
      if (psecond[i] < 0)
        psecond[i] += n;
    }

    // Second, complete the sort of cyclic substrings of
    // length 2^k by performing an in-place sort keyed by their first halves
    fill_n(begin(count), num_classes, 0);

    // Count the number of occurrences of each equivalence class
    // among cyclic substrings of length 2^{k-1}
    for (int i = 0; i < n; ++i)
      ++count[c[i]];
    for (int i = 1; i < num_classes; ++i)
      count[i] += count[i - 1];

    // Proceding in decreasing order sorted by second half,
    // put each index of the array at the last available spot of the
    // range, in sorted order, accorded to the equivalence class to which
    // the index's _first_ half belongs
    for (int i = n - 1; i >= 0; --i)
      p[--count[c[psecond[i]]]] = psecond[i];

    num_classes = 1;
    cnext[p[0]] = 0;
    for (int i = 1; i < n; ++i) {
      if (c[p[i]] == c[p[i - 1]] &&
          c[p[i] + (1 << h) % n] == c[p[i - 1] + (1 << h) % n]) {
        cnext[p[i]] = cnext[p[i - 1]];
      } else {
        cnext[p[i]] = cnext[p[i - 1]] + 1;
        ++num_classes;
      }
    }

    c.swap(cnext);
  }

  return p;
}

int main() {
  string T;
  cin >> T;
  T.push_back('$');

  auto suf = SortCyclicShifts(T);

  int q;
  cin >> q;
  string P;
  for (int i = 0; i < q; ++i) {
    cin >> P;
    auto res =
        lower_bound(begin(suf), end(suf), P, [&T](int x, const string &P) {
          string cmp = T.substr(x, P.size());
          return cmp < P;
        });
    cout << (res != end(suf) && (P == T.substr(*res, P.size()))) << endl;
  }
}


Error: 0

Fixed submission:

/*
 * Multiple string matching (suffix array)
 * O(T log T + \\sum (P_i log T))
 *
 * Construction: reduce to sorting the cyclic shifts of A||'$'
 */

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

constexpr int kAlphabetSize = 37;

int ValueOf(char ch) {
  if (ch == '$')
    return 0;
  if ('0' <= ch && ch <= '9')
    return 1 + ch - '0';
  if ('a' <= ch && ch <= 'z')
    return 11 + ch - 'a';
  cout << "Unexpected character!" << endl;
  exit(1);
  return -1;
}

vector<int> SortCyclicShifts(string &A) {
  // Approach: sort cyclic substrings of length 1, 2, 4, ..., 2^(\\ceil \\lg n)
  int n = A.size();

  // After step k,
  // p[i] stores the index (in A) of the ith-smallest (starting
  // from 0) cyclic substring of A of length 2^k;
  // c[i] stores the equivalence class (dense, starting from 0, in increasing
  // sorted value order) of the length-2^k substring starting at A[i]
  //
  // psecond and cnext are temporary arrays used to populate p and c each step
  // count is an auxiliary array used for bucket sort
  vector<int> p(n), c(n), psecond(n), cnext(n), count(max(n, kAlphabetSize));

  // Step 1: sort cyclic substrings of length 1
  for (int i = 0; i < n; ++i)
    ++count[ValueOf(A[i])];
  for (int i = 1; i < count.size(); ++i)
    count[i] += count[i - 1];
  for (int i = n - 1; i >= 0; --i)
    p[--count[ValueOf(A[i])]] = i;

  int num_classes = 1;
  for (int i = 1; i < n; ++i) {
    if (A[p[i]] != A[p[i - 1]]) {
      c[p[i]] = num_classes;
      ++num_classes;
    } else {
      c[p[i]] = c[p[i - 1]];
    }
  }

  // Step 2: for each k=1,...,ceil(log2(n)), use
  // the result of sorting the cyclic substrings of length 2^{k-1} to
  // sort the cyclic substrings of length 2^k
  for (int h /* k-1 */ = 0; (1 << h) < n; ++h) {
    // First, sort the cyclic substrings of length 2^k by their second halves;
    // to do this, directly apply the fact that the second half of a length
    // 2^k substring starting at index i is the length-2^{k-1} substring
    // starting at index (i+2^{k-1})
    for (int i = 0; i < n; ++i) {
      psecond[i] = p[i] - (1 << h);
      if (psecond[i] < 0)
        psecond[i] += n;
    }

    // Second, complete the sort of cyclic substrings of
    // length 2^k by performing an in-place sort keyed by their first halves
    fill_n(begin(count), num_classes, 0);

    // Count the number of occurrences of each equivalence class
    // among cyclic substrings of length 2^{k-1}
    for (int i = 0; i < n; ++i)
      ++count[c[i]];
    for (int i = 1; i < num_classes; ++i)
      count[i] += count[i - 1];

    // Proceding in decreasing order sorted by second half,
    // put each index of the array at the last available spot of the
    // range, in sorted order, accorded to the equivalence class to which
    // the index's _first_ half belongs
    for (int i = n - 1; i >= 0; --i)
      p[--count[c[psecond[i]]]] = psecond[i];

    num_classes = 1;
    cnext[p[0]] = 0;
    for (int i = 1; i < n; ++i) {
      if (c[p[i]] == c[p[i - 1]] &&
          c[p[i] + (1 << h) % n] == c[p[i - 1] + (1 << h) % n]) {
        cnext[p[i]] = cnext[p[i - 1]];
      } else {
        cnext[p[i]] = cnext[p[i - 1]] + 1;
        ++num_classes;
      }
    }

    c.swap(cnext);
  }

  return p;
}

int main() {
  string T;
  cin >> T;
  T.push_back('$');

  auto suf = SortCyclicShifts(T);

  int q;
  cin >> q;
  string P;
  for (int i = 0; i < q; ++i) {
    cin >> P;
    auto res =
        lower_bound(begin(suf), end(suf), P, [&T](int x, const string &P) {
          string cmp = T.substr(x, P.size());
          return cmp < P;
        });
    cout << (P == T.substr(*res, P.size())) << endl;
  }
}