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));
  rep(i, MAX + 1) d[i] = i;
  for (int i = 2; i <= MAX; i++) {
    // if (is_prime[i]) {
    if (d[i] == 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;
  while (/*not is_prime[x] && */ x > 1 && 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[MAX + 1];
int d[MAX + 1];

void erat() { // エラトステネスのふるい
  // memset(is_prime, true, sizeof(is_prime));
  rep(i, MAX + 1) d[i] = i;
  for (int i = 2; i <= MAX; i++) {
    // if (is_prime[i]) {
    if (d[i] == 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;
  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";
}