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

#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using ull = uint64_t;
const ll INF = 9e18;

void print() { cout << endl; }
template <typename Head, typename... Tail> void print(Head head, Tail... tail) {
  int size = sizeof...(Tail);
  cout << head;
  if (size > 0) {
    cout << " ";
  }
  print(tail...);
}

void print0() {}
template <typename Head, typename... Tail>
void print0(Head head, Tail... tail) {
  cout << head;
  print0(tail...);
}

vector<ll> mkprimes(ll N) {
  vector<bool> isprime(N + 1);
  vector<ll> primes;
  for (ll i = 0; i <= N; i++) {
    isprime[i] = true;
  }
  isprime[0] = false;
  isprime[1] = false;

  for (ll i = 2; i <= N; i++) {
    if (isprime[i]) {
      primes.push_back(i);
      for (ll j = 2 * i; j <= N; j += i) { // 素数iの倍数は素数ではない
        isprime[j] = false;
      }
    }
  }
  return primes;
}

vector<vector<ll>> prime_factors(ll m) {
  vector<vector<ll>> result(m + 1);

  vector<ll> primes = mkprimes(m);
  vector<bool> isprime(m + 1, false);
  for (auto p : primes) {
    isprime[p] = true;
  }

  for (ll nn = 2; nn <= m; nn++) {
    if (isprime[nn]) {
      result[nn].push_back(nn);
      continue;
    }
    ll n = nn;
    for (auto p : primes) {
      if (n % p == 0) {
        bool exist = false;
        for (ll pp : result[n / p]) {
          if (pp == p) {
            exist = true;
          }
          result[n].push_back(pp);
        }
        if (!exist) {
          result[n].push_back(p);
        }
        break;
      }
    }
  }
  return result;
}

int main() {
  ll N;
  cin >> N;
  vector<ll> A(N);
  for (ll i = 0; i < N; i++) {
    cin >> A[i];
  }
  ll maxval = 1000000;
  vector<vector<ll>> pfs = prime_factors(maxval);

  {
    bool pc = true;
    vector<bool> used(maxval + 1, false);
    for (ll i = 0; i < N; i++) {
      ll n = A[i];
      for (auto pf : pfs[n]) {
        if (used[pf]) {
          pc = false;
          break;
        }
        used[pf] = true;
      }
      if (!pc) {
        break;
      }
    }
    if (pc) {
      print("pairwise coprime");
      return 0;
    }
  }
  {
    vector<ll> usecount(maxval + 1, 0);
    for (ll i = 0; i < N; i++) {
      ll n = A[i];
      for (auto pf : pfs[n]) {
        usecount[pf]++;
      }
    }
    ll maxusecount = 0;
    for (auto u : usecount) {
      maxusecount = max(maxusecount, u);
    }
    if (maxusecount == N) {
      print("not coprime");
      return 0;
    } else {
      print("setwise coprime");
      return 0;
    }
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using ull = uint64_t;
const ll INF = 9e18;

void print() { cout << endl; }
template <typename Head, typename... Tail> void print(Head head, Tail... tail) {
  int size = sizeof...(Tail);
  cout << head;
  if (size > 0) {
    cout << " ";
  }
  print(tail...);
}

void print0() {}
template <typename Head, typename... Tail>
void print0(Head head, Tail... tail) {
  cout << head;
  print0(tail...);
}

vector<ll> mkprimes(ll N) {
  vector<bool> isprime(N + 1);
  vector<ll> primes;
  for (ll i = 0; i <= N; i++) {
    isprime[i] = true;
  }
  isprime[0] = false;
  isprime[1] = false;

  for (ll i = 2; i <= N; i++) {
    if (isprime[i]) {
      primes.push_back(i);
      for (ll j = 2 * i; j <= N; j += i) { // 素数iの倍数は素数ではない
        isprime[j] = false;
      }
    }
  }
  return primes;
}

const ll NMAX = 1000000;

// void prime_factor(ll n, set<ll>& res) {
//     for (ll i = 2; i * i <= n; i++) {
//         while (n % i == 0) {
//             res.insert(i);
//             n = n / i;
//         }
//     }
//     if (n != 1) {
//         res.insert(n);
//         //res[n] = 1;  // n自身が素数
//     }
// }

int main() {
  ll N;
  cin >> N;
  vector<ll> A(N);
  for (ll i = 0; i < N; i++) {
    cin >> A[i];
  }
  // set<ll> samefacts;
  // prime_factor(A[0], samefacts);
  // for (ll i = 1; i < N; i++) {
  //     //
  //     ll n = A[i];
  //     for (auto f : samefacts) {
  //         while (n % f == 0) {
  //             res.insert(f);
  //             n = n / f;
  //         }
  //     }
  //     if (n != 1) {
  //         res.insert(n);
  //     }
  //     //
  // }
  // ll pmax = 1002;

  ll AM = 1000000;
  auto primes = mkprimes(AM);
  vector<bool> primes2(AM, false);
  for (auto p : primes) {
    primes2[p] = true;
  }

  {
    bool pc = true;
    stack<ll> notused_a;
    stack<ll> notused_b;
    auto notused_current = &notused_a;
    auto notused_next = &notused_b;
    for (auto p : primes) {
      notused_a.push(p);
    }
    for (ll i = 0; i < N; i++) {
      ll ai = A[i];
      while (!notused_current->empty()) {
        ll p = notused_current->top();
        notused_current->pop();

        bool u = false;
        while (ai % p == 0) {
          ai = ai / p;
          u = true;
        }
        if (!u) {
          notused_next->push(p);
        }
      }
      if (ai != 1 && !primes2[ai]) {
        pc = false;
      }
      swap(notused_next, notused_current);
    }
    if (pc) {
      print("pairwise coprime");
      return 0;
    }
  }
  {
    bool nc = true;
    stack<ll> used_a;
    stack<ll> used_b;
    auto used_current = &used_a;
    auto used_next = &used_b;
    for (auto p : primes) {
      used_a.push(p);
    }
    for (ll i = 0; i < N; i++) {
      ll ai = A[i];
      while (!used_current->empty()) {
        ll p = used_current->top();
        used_current->pop();
        if (ai % p == 0) {
          // print(A[i], p, "used");
          used_next->push(p);
        }
      }
      if (used_next->empty()) {
        nc = false;
      }
      swap(used_next, used_current);
    }
    if (nc) {
      print("not coprime");
      return 0;
    } else {
      print("setwise coprime");
      return 0;
    }
  }

  // vector<vector<ll>> factors(N);
  // vector<ll> usedprimes(pmax, 0);
  // bool allsame = true;
  // for (ll i = 0; i < N; i++) {
  //     if (i > 0 && A[i] != A[i - 1]) {
  //         allsame = false;
  //     }
  //     ll mx = 1.0 + sqrt(A[i]);
  //     for (ll p = 0; p < primes.size(); p++) {
  //         ll pr = primes[p];
  //         if (A[i] % pr == 0) {
  //             usedprimes[pr]++;
  //         }
  //         if (pr >= mx) {
  //             break;
  //         }
  //     }
  // }
  // if (allsame) {
  //     print("not coprime");
  //     return 0;
  // }
  // ll maxused = 0;
  // for (auto u : usedprimes) {
  //     maxused = max(u, maxused);
  // }
  // if (maxused == N) {
  //     print("not coprime");
  // } else if (maxused >= 2) {
  //     print("setwise coprime");
  // } else {
  //     print("pairwise coprime");
  // }
}