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

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

#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define ALL(x) x.begin(), x.end()

using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;

const ll INF = 1e18;
const int mod = 1e9 + 7;
const int MAX = 1e6;

// int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

struct edge {
  int to, cost;
}; // 辺
// vector<edge> graph[MAX]; // 隣接リスト
// bool visit[MAX]; // 訪問の有無

int gcd(int a, int b) { // aとbの最大公約数（ユークリッドの互除法）
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

bool is_prime[MAX + 1];
int d[MAX + 1];

void erat() { // エラトステネスのふるい
  memset(is_prime, true, sizeof(is_prime));
  for (int i = 2; i <= MAX; i++) {
    if (is_prime[i]) {
      for (int j = i + i; j <= MAX; j += i) {
        is_prime[j] = false;
        d[j] = i;
      }
    }
  }
}

void prime_fact(int x, set<int> &fact) { // 素因数分解
  if (x < 2)
    return;
  // for (int i = 2; i * i <= x; i++) {
  //     if (x % i == 0) {
  //         fact.insert(i);
  //         while (x % i == 0) x /= i;
  //     }
  // }
  // if (x != 1) fact.insert(x);
  while (not is_prime[x] && x % d[x] == 0) {
    fact.insert(d[x]);
    x /= d[x];
  }
  if (x != 1) {
    fact.insert(x);
  }
}

int n;
int a[MAX];
set<int> s;
bool flag = true;

int main() {
  // input
  erat();
  cin >> n;
  rep(i, n) { cin >> a[i]; }
  // solve
  rep(i, n) {
    if (a[i] == 1)
      continue;
    if (flag) {
      set<int> fact;
      prime_fact(a[i], fact);
      for (int x : fact) {
        if (not s.count(x)) {
          s.insert(x);
        } else {
          flag = false;
          break;
        }
      }
    }
    if (i > 0)
      a[i] = gcd(a[i], a[i - 1]);
  }
  // output
  if (flag)
    cout << "pairwise coprime"
         << "\\n";
  else {
    if (a[n - 1] == 1)
      cout << "setwise coprime"
           << "\\n";
    else
      cout << "not coprime"
           << "\\n";
  }
}

Error: TLE

Fixed submission:

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

#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define ALL(x) x.begin(), x.end()

using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;

const ll INF = 1e18;
const int mod = 1e9 + 7;
const int MAX = 1e6;

// int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

struct edge {
  int to, cost;
}; // 辺
// vector<edge> graph[MAX]; // 隣接リスト
// bool visit[MAX]; // 訪問の有無

int gcd(int a, int b) { // aとbの最大公約数（ユークリッドの互除法）
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

bool is_prime(int n) { // 素数判定
  if (n == 2)
    return true;
  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0)
      return false;
  }
  return true;
}

void prime_fact(int x, set<int> &f) { // 素因数分解
  if (x < 2)
    return;
  for (int i = 2; i * i <= x; i++) {
    if (x % i == 0) {
      f.insert(i);
      while (x % i == 0)
        x /= i;
    }
  }
  if (x != 1)
    f.insert(x);
}

int n;
int a[MAX];
set<int> s;
bool flag = true;

int main() {
  // input
  cin >> n;
  rep(i, n) { cin >> a[i]; }
  // solve
  rep(i, n) {
    if (flag) {
      set<int> f;
      prime_fact(a[i], f);
      set<int> s_and_f;
      set_intersection(ALL(s), ALL(f), inserter(s_and_f, s_and_f.end()));
      // set<int> u;
      if (s_and_f.empty()) {
        // set_union(ALL(s), ALL(f), inserter(u, u.end()));
        // s = u;
        for (int x : f)
          s.insert(x);
      } else
        flag = false;
    }
    if (i > 0)
      a[i] = gcd(a[i], a[i - 1]);
  }
  // output
  if (flag)
    cout << "pairwise coprime"
         << "\\n";
  else {
    if (a[n - 1] == 1)
      cout << "setwise coprime"
           << "\\n";
    else
      cout << "not coprime"
           << "\\n";
  }
}