Problem p04022 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

using i64 = long long;

const int N = 1e5 + 5, C = 4096;

map<i64, i64> van, mp;
vector<i64> v, primes;
bitset<N> bit, mo;
int n, ant;

static void find(i64 x) {
  i64 &dual = van[x];
  i64 sqr, tx;
  int cnt;

  tx = x;
  dual = 1;
  for (auto i : primes) {
    if (x % i == 0) {
      cnt = 1;
      x /= i;
      if (x % i == 0) {
        cnt += 1;
        x /= i;
      }

      switch (cnt) {
      case 1: {
        dual *= i * i;
        break;
      }
      case 2: {
        dual *= i;
        break;
      }
      }
    }
  }

  if (x == 1) {
    van[dual] = tx;
    return;
  }
  sqr = sqrt(x) + 0.5;

  if (sqr * sqr == x) {
    dual *= sqr;
    van[dual] = tx;
    return;
  }

  dual *= x * x;
  van[dual] = x;
}

int main() {
#ifdef HOME
  freopen("agc3d.in", "r", stdin);
  freopen("agc3d.out", "w", stdout);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  i64 drop;

  cin >> n;
  v.resize(n);
  for (auto &i : v)
    cin >> i;

  bit = 3;
  for (int i = 2; i * i < N; ++i)
    if (!bit[i])
      for (int j = i * i; j < N; j += i)
        bit[j] = 1;
  for (int i = 0; i < N; ++i)
    if (!bit[i])
      primes.push_back(i);

  mo = 0, mo.flip();
  for (int i = 2; i * i < N; ++i)
    for (int j = i * i; j < N; j += i * i)
      mo[j] = 0;

  for (int i = 2; i < C; ++i)
    if (!bit[i]) {
      for (auto &j : v)
        while (j % (1LL * i * i * i) == 0)
          j /= 1LL * i * i * i;
    }

  for (int i = 0; i < v.size(); ++i)
    if (v[i] == 1) {
      if (ant == 0)
        ant = 1;
      swap(v[i--], v.back());
      v.pop_back();
    }
  n = v.size();

  for (int i = 0; i < n; ++i) {
    mp[v[i]] += 1;
    find(v[i]);
  }

  for (int i = 0; i < n; ++i) {
    i64 &x = mp[v[i]];
    i64 &y = mp[van[v[i]]];

    drop = max(x, y);
    ant += drop;
    x -= drop;
    y -= drop;
  }

  cout << ant << endl;

  return 0;
}


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

using i64 = long long;

const int N = 1e5 + 5, C = 4096;

map<i64, i64> van, mp;
vector<i64> v, primes;
bitset<N> bit, mo;
int n, ant;

static void find(i64 x) {
  i64 &dual = van[x];
  i64 sqr, tx;
  int cnt;

  tx = x;
  dual = 1;
  for (auto i : primes) {
    if (x % i == 0) {
      cnt = 1;
      x /= i;
      if (x % i == 0) {
        cnt += 1;
        x /= i;
      }

      switch (cnt) {
      case 1: {
        dual *= i * i;
        break;
      }
      case 2: {
        dual *= i;
        break;
      }
      }
    }
  }

  if (x == 1) {
    van[dual] = tx;
    return;
  }
  sqr = sqrt(x) + 0.5;

  if (sqr * sqr == x) {
    dual *= sqr;
    van[dual] = tx;
    return;
  }

  dual *= x * x;
  van[dual] = x;
}

int main() {
#ifdef HOME
  freopen("agc3d.in", "r", stdin);
  freopen("agc3d.out", "w", stdout);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  i64 drop;

  cin >> n;
  v.resize(n);
  for (auto &i : v)
    cin >> i;

  bit = 3;
  for (int i = 2; i * i < N; ++i)
    if (!bit[i])
      for (int j = i * i; j < N; j += i)
        bit[j] = 1;
  for (int i = 0; i < C; ++i)
    if (!bit[i])
      primes.push_back(i);

  mo = 0, mo.flip();
  for (int i = 2; i * i < N; ++i)
    for (int j = i * i; j < N; j += i * i)
      mo[j] = 0;

  for (int i = 2; i < C; ++i)
    if (!bit[i]) {
      for (auto &j : v)
        while (j % (1LL * i * i * i) == 0)
          j /= 1LL * i * i * i;
    }

  for (int i = 0; i < v.size(); ++i)
    if (v[i] == 1) {
      if (ant == 0)
        ant = 1;
      swap(v[i--], v.back());
      v.pop_back();
    }
  n = v.size();

  for (int i = 0; i < n; ++i) {
    mp[v[i]] += 1;
    find(v[i]);
  }

  for (int i = 0; i < n; ++i) {
    i64 &x = mp[v[i]];
    i64 &y = mp[van[v[i]]];

    drop = max(x, y);
    ant += drop;
    x -= drop;
    y -= drop;
  }

  cout << ant << endl;

  return 0;
}