Problem p04022 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pi;
typedef vector<pi> vpi;
typedef long double ld;
#define pb emplace_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define ALL(x) x.begin(), x.end()
#define SZ(x) (ll) x.size()
#define f first
#define s second
#define MAXN 100100

bitset<2300> bs;
vi primes;
vi cubes;
ll N;
ll A[MAXN];
ll ans;
map<ll, pi> M;
ll B[MAXN];

int main() {
  bs.set();
  for (ll i = 2; i <= 2200; ++i)
    if (bs[i]) {
      primes.pb(i);
      for (ll j = i * i; j <= 2200; j += i)
        bs[j] = 0;
    }
  for (auto i : primes)
    cubes.pb(i * i * i);
  cin >> N;
  for (ll i = 1; i <= N; ++i) {
    cin >> A[i];
    for (auto x : cubes)
      while (A[i] % x == 0)
        A[i] /= x;
    ll t = A[i];
    for (auto i : primes)
      while (t % i == 0)
        t /= i;
    if (t == 1)
      continue;
    // Only way to not bust is if t is a square number or a prime number
    ll rt = floor(sqrt(t));
    if (rt * rt == t) {
      B[i] = rt;
    } else if (t > 100000) {
      ++ans;
      A[i] = 0;
    }
  }
  ll ones = 0;
  for (ll i = 1; i <= N; ++i)
    if (A[i]) {
      if (A[i] == 1) {
        ++ones;
        continue;
      }
      ll opp = 1;
      ll act = A[i];
      for (auto j : primes) {
        if (A[i] % (j * j) == 0)
          opp *= j, A[i] /= (j * j);
        else if (A[i] % j == 0)
          opp *= j * j, A[i] /= j;
      }
      if (A[i] != 1) {
        assert(B[i] != 0);
        opp *= B[i];
      }
      assert(opp != act);
      if (opp > act) {
        M[act].f++;
      } else {
        M[opp].s++;
      }
    }
  for (auto i : M)
    ans += max(i.s.f, i.s.s);
  if (ones)
    ++ans;
  cout << ans;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pi;
typedef vector<pi> vpi;
typedef long double ld;
#define pb emplace_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define ALL(x) x.begin(), x.end()
#define SZ(x) (ll) x.size()
#define f first
#define s second
#define MAXN 100100

bitset<2300> bs;
vi primes;
vi cubes;
ll N;
ll A[MAXN];
ll ans;
map<ll, pi> M;
ll B[MAXN];

int main() {
  bs.set();
  for (ll i = 2; i <= 2200; ++i)
    if (bs[i]) {
      primes.pb(i);
      for (ll j = i * i; j <= 2200; j += i)
        bs[j] = 0;
    }
  for (auto i : primes)
    cubes.pb(i * i * i);
  cin >> N;
  for (ll i = 1; i <= N; ++i) {
    cin >> A[i];
    for (auto x : cubes)
      while (A[i] % x == 0)
        A[i] /= x;
    ll t = A[i];
    for (auto i : primes)
      while (t % i == 0)
        t /= i;
    if (t == 1)
      continue;
    // Only way to not bust is if t is a square number or a prime number
    ll rt = floor(sqrt(t));
    if (rt * rt == t) {
      B[i] = rt;
    } else if (t > 100000) {
      ++ans;
      A[i] = 0;
    } else {
      B[i] = A[i] * A[i];
    }
  }
  ll ones = 0;
  for (ll i = 1; i <= N; ++i)
    if (A[i]) {
      if (A[i] == 1) {
        ++ones;
        continue;
      }
      ll opp = 1;
      ll act = A[i];
      for (auto j : primes) {
        if (A[i] % (j * j) == 0)
          opp *= j, A[i] /= (j * j);
        else if (A[i] % j == 0)
          opp *= j * j, A[i] /= j;
      }
      if (A[i] != 1) {
        assert(B[i] != 0);
        opp *= B[i];
      }
      assert(opp != act);
      if (opp > act) {
        M[act].f++;
      } else {
        M[opp].s++;
      }
    }
  for (auto i : M)
    ans += max(i.s.f, i.s.s);
  if (ones)
    ++ans;
  cout << ans;
}