Problem p04022 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

long long n;
long long a[(1 << 20)], f[(1 << 20)];

vector<long long> prs;

pair<long long, long long> vals[(1 << 20)];
map<long long, long long> cnt;
map<long long, pair<long long, long long>> mem;

pair<long long, long long> gg(long long x) {

  // if ( mem.count( x ) ) { return mem[x]; }

  long long a = 1, b = 1;

  for (int i = 0; i < prs.size() && prs[i] * prs[i] <= x; i++) {

    if (x % prs[i] == 0) {
      int cnt = 0;
      for (; x % prs[i] == 0; cnt++) {
        x /= prs[i];
      }
      cnt %= 3;
      for (int c = 0; c < cnt; c++) {
        a *= prs[i];
      }
      cnt = (3 - cnt) % 3;

      for (int c = 0; c < cnt; c++) {
        if (b != -1) {
          b *= prs[i];
          if (b > (10000000000LL)) {
            b = -1;
          }
        }
      }
    }
  }

  if (x != 1) {
    a *= x;
    if (x > 1000000) {
      b = -1;
    }
    if (b != -1) {
      b *= x;
      if (b > (10000000000LL)) {
        b = -1;
      }
    }
    if (b != -1) {
      b *= x;
      if (b > (10000000000LL)) {
        b = -1;
      }
    }
  }

  mem[x] = make_pair(a, b);
  return make_pair(a, b);
}

int main() {

  for (long long i = 2; i * i < (10000000000LL); i++) {
    if (f[i] == 0) {
      prs.push_back(i);
      for (long long j = 1; i * i * j * j < (10000000000LL); j++) {
        f[i * j] = 1;
      }
    }
  }

  cin >> n;
  for (long long i = 0; i < n; i++) {
    cin >> a[i];
    vals[i] = gg(a[i]);
    //   cout << vals[i].first << " " << vals[i].second << "\n";
    cnt[vals[i].first]++;
  }
  sort(vals, vals + n);

  long long ans = 0;
  for (long long i = 0; i < n;) {
    long long j = i;
    for (; j < n && vals[i].first == vals[j].first; j++) {
    }

    long long ccnt = j - i, revcnt = cnt[vals[i].second];

    if (vals[i].first == 1) {
      ans++;
    } else {
      if (ccnt > revcnt) {
        ans += ccnt;
      } else if (ccnt < revcnt) {
        // ans += revcnt;
      } else {
        if (vals[i].first < vals[i].second) {
          ans += ccnt;
        }
      }
    }

    i = j;
  }
  cout << ans << "\n";
  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

long long n;
long long a[(1 << 20)], f[(1 << 20)];

vector<long long> prs;

pair<long long, long long> vals[(1 << 20)];
map<long long, long long> cnt;
map<long long, pair<long long, long long>> mem;

pair<long long, long long> gg(long long x) {

  // if ( mem.count( x ) ) { return mem[x]; }

  long long a = 1, b = 1;

  for (int i = 0; i < prs.size() && prs[i] * prs[i] <= x; i++) {

    if (x % prs[i] == 0) {
      int cnt = 0;
      for (; x % prs[i] == 0; cnt++) {
        x /= prs[i];
      }
      cnt %= 3;
      for (int c = 0; c < cnt; c++) {
        a *= prs[i];
      }
      cnt = (3 - cnt) % 3;

      for (int c = 0; c < cnt; c++) {
        if (b != -1) {
          b *= prs[i];
          if (b > (10000000000LL)) {
            b = -1;
          }
        }
      }
    }
  }

  if (x != 1) {
    a *= x;
    if (x > 1000000) {
      b = -1;
    }
    if (b != -1) {
      b *= x;
      if (b > (10000000000LL)) {
        b = -1;
      }
    }
    if (b != -1) {
      b *= x;
      if (b > (10000000000LL)) {
        b = -1;
      }
    }
  }

  mem[x] = make_pair(a, b);
  return make_pair(a, b);
}

int main() {

  for (long long i = 2; i * i < (10000000000LL); i++) {
    if (f[i] == 0) {
      prs.push_back(i);
      for (long long j = 1; i * i * j * j < (10000000000LL); j++) {
        f[i * j] = 1;
      }
    }
  }

  cin >> n;
  for (long long i = 0; i < n; i++) {
    cin >> a[i];
  }
  sort(a, a + n);
  for (int i = 0; i < n; i++) {
    if (i == 0 || a[i] != a[i - 1]) {
      vals[i] = gg(a[i]);
    } else {
      vals[i] = vals[i - 1];
    }
    //   cout << vals[i].first << " " << vals[i].second << "\n";
    cnt[vals[i].first]++;
  }
  sort(vals, vals + n);

  long long ans = 0;
  for (long long i = 0; i < n;) {
    long long j = i;
    for (; j < n && vals[i].first == vals[j].first; j++) {
    }

    long long ccnt = j - i, revcnt = cnt[vals[i].second];

    if (vals[i].first == 1) {
      ans++;
    } else {
      if (ccnt > revcnt) {
        ans += ccnt;
      } else if (ccnt < revcnt) {
        // ans += revcnt;
      } else {
        if (vals[i].first < vals[i].second) {
          ans += ccnt;
        }
      }
    }

    i = j;
  }
  cout << ans << "\n";
  return 0;
}