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

#include <bits/stdc++.h>

using namespace std;

#define MAX_N 1000001

int n, k, sa[MAX_N];
int rank[MAX_N], tmp[MAX_N];

bool compare_sa(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;
  }
}

void construct_sa(string &S, int *sa) {
  n = S.length();

  for (int i = 0; i <= n; i++) {
    sa[i] = i;
    rank[i] = i < n ? S[i] : -1;
  }

  for (k = 1; k <= n; k *= 2) {
    sort(sa, sa + n + 1, compare_sa);

    tmp[sa[0]] = 0;
    for (int i = 1; i <= n; i++) {
      tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
    }
    for (int i = 0; i <= n; i++) {
      rank[i] = tmp[i];
    }
  }
}

bool contain(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;
}

int main() {
  ios::sync_with_stdio(0);

  int Q;
  string S, T;
  cin >> S >> Q;
  construct_sa(S, sa);
  while (Q--) {
    cin >> T;
    if (S.size() < T.size()) {
      cout << '0' << endl;
      continue;
    }
    cout << (contain(S, sa, T) ? '1' : '0') << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef vector<int> Vec;

struct PMA {
  PMA *next[256];
  Vec matched;
  PMA() { fill(next, next + 256, (PMA *)0); }
  ~PMA() {
    for (int i = 0; i < 256; i++) {
      if (next[i])
        delete next[i];
    }
    matched.clear();
  }
};

Vec set_union(const Vec &a, const Vec &b) {
  int i = 0, j = 0, A = a.size(), B = b.size();
  Vec res;
  while (i < A && j < B) {
    if (a[i] == b[j]) {
      res.push_back(a[i]);
      i++;
      j++;
    } else if (a[i] > b[j]) {
      res.push_back(b[j++]);
    } else {
      res.push_back(a[i++]);
    }
  }
  for (; i < A; i++)
    res.push_back(a[i]);
  for (; j < B; j++)
    res.push_back(b[j]);
  return res;
}

PMA *buildPMA(char *pattern[], int size) {
  PMA *root = new PMA;
  for (int i = 0; i < size; i++) {
    PMA *t = root;
    for (int j = 0; pattern[i][j] != '\\0'; j++) {
      char c = pattern[i][j];
      if (t->next[c] == (PMA *)0)
        t->next[c] = new PMA;
      t = t->next[c];
    }
    t->matched.push_back(i);
  }
  queue<PMA *> Q;
  for (int i = 1; i < 256; i++) {
    if (root->next[i]) {
      root->next[i]->next[0] = root;
      Q.push(root->next[i]);
    } else {
      root->next[i] = root;
    }
  }
  while (!Q.empty()) {
    PMA *t = Q.front();
    Q.pop();
    for (int i = 1; i < 256; i++) {
      if (t->next[i]) {
        PMA *next = t->next[0];
        while (!next->next[i])
          next = next->next[0];
        t->next[i]->next[0] = next->next[i];
        t->next[i]->matched =
            set_union(t->next[i]->matched, next->next[i]->matched);
        Q.push(t->next[i]);
      }
    }
  }
  return root;
}

void match(PMA *pma, const char *s, Vec &res) {
  for (int i = 0; s[i] != '\\0'; i++) {
    int c = s[i];
    while (!pma->next[c])
      pma = pma->next[0];
    pma = pma->next[c];
    for (int j = 0; j < (int)pma->matched.size(); j++) {
      res[pma->matched[j]] = 1;
    }
  }
}

char T[1000001];
char *P[10000];

int main() {
  int Q;
  scanf("%s%d", T, &Q);
  for (int i = 0; i < Q; i++) {
    P[i] = new char;
    scanf("%s", P[i]);
  }
  PMA *pma = buildPMA(P, Q);
  Vec res(Q, 0);
  match(pma, T, res);
  for (int i = 0; i < (int)res.size(); i++) {
    printf("%d\\n", res[i]);
  }
  return 0;
}