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

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

struct PrimeNumbers {
  int max;
  vector<bool>
      is_prime; // i-th element is true iff i is prime (i <= max). (e.g.
                // is_prime = {false, false, true, true, false} for max = 4)
  vector<int> primes; // The list of prime numbers less than or equal to max.
                      // (e.g. primes = {2, 3} for max = 4)
  vector<int> minimum_factor; // The list of the minimum factors of the integers
                              // less than or equal to max. (e.g. minimum_factor
                              // = {0, 1, 2, 3, 2} for max = 4)

  PrimeNumbers(int max) : max(max) {
    is_prime = vector<bool>(max + 1, true);
    is_prime.at(0) = is_prime.at(1) = false;
    for (int i = 0; i <= max; ++i)
      minimum_factor.emplace_back(i);

    for (int i = 2; i * i <= max; ++i)
      if (is_prime.at(i))
        for (int j = i * i; j <= max; j += i) {
          is_prime.at(j) = false;
          if (minimum_factor.at(j) == j)
            minimum_factor.at(j) = i;
        }
    for (int i = 2; i <= max; ++i)
      if (is_prime.at(i))
        primes.emplace_back(i);
  }

  // Return the list of the prime factors of n. (2 <= n < (max + 1)^2)
  // (e.g. prime_factorization(24) = {2, 2, 2, 3})
  // Use a fast algorithm for n <= max.
  template <typename T> vector<T> prime_factorization(T n) {
    vector<T> factors;
    try {
      if (n < 2 || n / (max + 1) >= (max + 1))
        throw "The argument of prime_factorization() is out of range.";
    } catch (char const *str) {
      cout << str << endl;
    }

    if (n <= max) {
      while (n != 1) {
        factors.emplace_back(minimum_factor.at(n));
        n /= minimum_factor.at(n);
      }
    } else {
      for (int p : primes) {
        if (n == 1)
          return factors;
        while (n % p == 0) {
          factors.emplace_back(p);
          n /= p;
        }
      }
      if (n != 1)
        factors.emplace_back(n);
    }

    return factors;
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  PrimeNumbers pm(1000);

  int n;
  cin >> n;
  vector<int> a(n);
  int a_max = 0;
  rep(i, n) {
    cin >> a.at(i);
    a_max = max(a_max, a.at(i));
  }

  PrimeNumbers pn(a_max);
  unordered_set<int> factors;
  vector<int> n_factors(a_max + 1);

  for (int i : a) {
    factors.clear();
    for (int p : i != 1 ? pn.prime_factorization(i) : vector<int>(1, 1))
      factors.emplace(p);
    for (int p : factors)
      n_factors.at(p)++;
  }

  bool pairwise_coprime = true;

  for (int i = 2; i <= a_max; ++i) {
    if (n_factors.at(i) == n) {
      printf("not coprime\\n");
      return 0;
    }
    if (n_factors.at(i) > 1)
      pairwise_coprime = false;
  }

  if (pairwise_coprime)
    printf("pairwise coprime\\n");
  else
    printf("setwise coprime\\n");

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

struct PrimeNumbers {
  int max;
  vector<bool>
      is_prime; // i-th element is true iff i is prime (i <= max). (e.g.
                // is_prime = {false, false, true, true, false} for max = 4)
  vector<int> primes; // The list of prime numbers less than or equal to max.
                      // (e.g. primes = {2, 3} for max = 4)
  vector<int> minimum_factor; // The list of the minimum factors of the integers
                              // less than or equal to max. (e.g. minimum_factor
                              // = {0, 1, 2, 3, 2} for max = 4)

  PrimeNumbers(int max) : max(max) {
    is_prime = vector<bool>(max + 1, true);
    is_prime.at(0) = is_prime.at(1) = false;
    for (int i = 0; i <= max; ++i)
      minimum_factor.emplace_back(i);

    for (int i = 2; i * i <= max; ++i)
      if (is_prime.at(i))
        for (int j = i * i; j <= max; j += i) {
          is_prime.at(j) = false;
          if (minimum_factor.at(j) == j)
            minimum_factor.at(j) = i;
        }
    for (int i = 2; i <= max; ++i)
      if (is_prime.at(i))
        primes.emplace_back(i);
  }

  // Return the list of the prime factors of n. (2 <= n < (max + 1)^2)
  // (e.g. prime_factorization(24) = {2, 2, 2, 3})
  // Use a fast algorithm for n <= max.
  template <typename T> vector<T> prime_factorization(T n) {
    vector<T> factors;
    try {
      if (n < 2 || n / (max + 1) >= (max + 1))
        throw "The argument of prime_factorization() is out of range.";
    } catch (char const *str) {
      cout << str << endl;
    }

    if (n <= max) {
      while (n != 1) {
        factors.emplace_back(minimum_factor.at(n));
        n /= minimum_factor.at(n);
      }
    } else {
      for (int p : primes) {
        if (n == 1)
          return factors;
        while (n % p == 0) {
          factors.emplace_back(p);
          n /= p;
        }
      }
      if (n != 1)
        factors.emplace_back(n);
    }

    return factors;
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  PrimeNumbers pm(1000);

  int n;
  cin >> n;
  vector<int> a(n);
  int a_max = 0;
  rep(i, n) {
    cin >> a.at(i);
    a_max = max(a_max, a.at(i));
  }

  PrimeNumbers pn(a_max);
  unordered_set<int> factors;
  vector<int> n_factors(a_max + 1);

  for (int i : a) {
    factors.clear();
    for (int p : pn.prime_factorization(i))
      factors.emplace(p);
    for (int p : factors)
      n_factors.at(p)++;
  }

  bool pairwise_coprime = true;

  for (int i = 2; i <= n; ++i) {
    if (n_factors.at(i) == n) {
      printf("not coprime\\n");
      return 0;
    }
    if (n_factors.at(i) > 1)
      pairwise_coprime = false;
  }

  if (pairwise_coprime)
    printf("pairwise coprime\\n");
  else
    printf("setwise coprime\\n");

  return 0;
}