Problem p04022 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

typedef unsigned uint;
typedef long long Int;
typedef unsigned long long UInt;

const int INF = 1001001001;
const Int INFLL = 1001001001001001001LL;

template <typename T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cout << *i << " ";
  cout << endl;
}
template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}
int in() {
  int x;
  scanf("%d", &x);
  return x;
}
double fin() {
  double x;
  scanf("%lf", &x);
  return x;
}
Int lin() {
  Int x;
  scanf("%lld", &x);
  return x;
}

Int S[100050];
int isp[100050];

int main() {
  int N = in();
  map<Int, int> X;
  for (int i = 0; i < N; ++i) {
    Int v = (S[i] = lin());
    for (Int d = 2; d * d * d <= v; ++d) {
      while (v % (d * d * d) == 0) {
        v /= d * d * d;
      }
    }
    ++X[v];
  }

  fill(isp + 2, isp + 100050, 1);
  vector<Int> prs;
  for (int i = 2; i < 100050; ++i) {
    if (isp[i]) {
      prs.push_back(i);
      for (int j = i + i; j < 100050; j += i) {
        isp[j] = 0;
      }
    }
  }

  int res = 0;
  for (const auto &p : X) {
    if (p.first == 1) {
      continue;
    }
    const int cnt = p.second;

    Int p1 = 1, p2 = 1, v = p.first;
    for (int i = 0; i < (int)prs.size() && prs[i] * prs[i] <= v; ++i) {
      const Int pr = prs[i];
      if (v % (pr * pr) == 0) {
        p2 *= pr;
        v /= pr * pr;
      } else if (v % pr == 0) {
        p1 *= pr;
        v /= pr;
      }
    }

    const Int sqrtv = (Int)(sqrt(v) + 0.5);
    if (sqrtv * sqrtv == v && isp[sqrtv]) {
      p2 *= sqrtv;
    } else {
      p1 *= v;
    }

    if (p1 > 100050 || X.count(p1 * p1 * p2) == 0) {
      res += 2 * cnt;
      continue;
    }
    res += max(cnt, X[p1 * p1 * p2]);
  }
  res /= 2;

  printf("%d\n", res + (X.count(1) > 0 ? 1 : 0));

  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

typedef unsigned uint;
typedef long long Int;
typedef unsigned long long UInt;

const int INF = 1001001001;
const Int INFLL = 1001001001001001001LL;

template <typename T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cout << *i << " ";
  cout << endl;
}
template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}
int in() {
  int x;
  scanf("%d", &x);
  return x;
}
double fin() {
  double x;
  scanf("%lf", &x);
  return x;
}
Int lin() {
  Int x;
  scanf("%lld", &x);
  return x;
}

Int S[100050];
int isp[100050];

int main() {
  int N = in();
  map<Int, int> X;
  for (int i = 0; i < N; ++i) {
    Int v = (S[i] = lin());
    for (Int d = 2; d * d * d <= v; ++d) {
      while (v % (d * d * d) == 0) {
        v /= d * d * d;
      }
    }
    ++X[v];
  }

  fill(isp + 2, isp + 100050, 1);
  vector<Int> prs;
  for (int i = 2; i < 100050; ++i) {
    if (isp[i]) {
      prs.push_back(i);
      for (int j = i + i; j < 100050; j += i) {
        isp[j] = 0;
      }
    }
  }

  int res = 0;
  for (const auto &p : X) {
    if (p.first == 1) {
      continue;
    }
    const int cnt = p.second;

    Int p1 = 1, p2 = 1, v = p.first;
    for (int i = 0; i < (int)prs.size() && prs[i] * prs[i] * prs[i] <= v; ++i) {
      const Int pr = prs[i];
      if (v % (pr * pr) == 0) {
        p2 *= pr;
        v /= pr * pr;
      } else if (v % pr == 0) {
        p1 *= pr;
        v /= pr;
      }
    }

    const Int sqrtv = (Int)(sqrt(v) + 0.5);
    if (sqrtv * sqrtv == v && isp[sqrtv]) {
      p2 *= sqrtv;
    } else {
      p1 *= v;
    }

    if (p1 > 100050 || X.count(p1 * p1 * p2) == 0) {
      res += 2 * cnt;
      continue;
    }
    res += max(cnt, X[p1 * p1 * p2]);
  }
  res /= 2;

  printf("%d\n", res + (X.count(1) > 0 ? 1 : 0));

  return 0;
}