Problem p04022 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#include <stdio.h>

using namespace std;

typedef double db;
typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;

typedef pair<db, db> pdd;
typedef pair<db, ld> pdl;
typedef pair<ld, db> pld;
typedef pair<ld, ld> ldp;

typedef pair<ll, ll> pll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<int, int> pii;

#define f first
#define s second

#define en end()
#define bg begin()

#define rev reverse
#define mp make_pair
#define pb push_back

#define y1 y1234567890
#define um unordered_map

#define all(x) x.bg, x.en
#define sz(x) (int)x.size()
#define len(x) (int)strlen(x)

#define sqr(x) ((x + 0ll) * (x))
#define sqrd(x) ((x + 0.0) * (x))

#define forn(i, n) for (int i = 1; i <= n; i++)

const ll inf = (ll)1e18;

const db eps = (db)1e-9;
const db pi = acos(-1.0);

const ll NM = (ll)1e18;
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 300500;

int n;
ll d[N], ans;
map<ll, int> m;
set<ll> s;
vector<ll> pr;

ll mul_mod(ll a, ll b, ll mod) {
  if (NM / a >= b)
    return a * b % mod;
  ll res = 0;
  while (b) {
    if (b & 1)
      res = (res + a) % mod;
    a = (a * 2ll) % mod;
    b >>= 1;
  }
  return res;
}
ll powm(ll p, ll n, ll mod) {
  ll res = 1;
  while (n) {
    if (n & 1)
      res = mul_mod(res, p, mod);
    p = mul_mod(p, p, mod);
    n >>= 1;
  }
  return res;
}
bool mrt(ll p) {
  if (p == 1)
    return false;
  for (int i = 0; i < 430; ++i) {
    ll j = pr[i];
    if (j * j > p)
      break;
    if (p % j == 0)
      return false;
  }
  ll s = 0, d = p - 1;
  while (!(d & 1)) {
    d = d / 2;
    s++;
  }
  srand(time(NULL)); /// Генерируем действительно случайные и разные a
  for (int i = 1; i <= 5; ++i) { /// Те самые 5 проверок
    ll a = rand() % p;
    if (a == 0)
      a++;
    bool flag1 = false, flag2 = false;
    if (powm(a % p, d, p) == 1) /// Первая проверка
      flag1 = true;
    if (!flag1)
      for (int r = 0; r < s; ++r) /// Вторая проверка
        if (powm(a % p, (1LL << r) * d, p) == p - 1)
          flag2 = true;
    if (!flag1 && !flag2)
      return false;
  }
  return true;
}

int main() {
  // freopen(".in", "r", stdin);
  // freopen(".out", "w", stdout);
  // freopen(".err", "w", stderr);

  // srand(time(NULL));

  // cin.tie(NULL);
  // cout.tie(NULL);
  // ios_base::sync_with_stdio(false);

  // cout << setprecision(10) << fixed;

  int n;
  cin >> n;

  for (int i = 2; i <= 3000; ++i) {
    bool ok = 1;
    for (int j = 2; j * j <= i; ++j)
      if (i % j == 0)
        ok = 0;
    if (ok)
      pr.pb(i);
  }

  for (int i = 1; i <= n; ++i) {
    ll x;
    cin >> x;
    // x = (ll)1e10 - i + 1;
    mrt(x);
    for (ll j = 0; j < 430; ++j) {
      ll w = pr[j];
      while (x % (w * w * w) == 0)
        x /= (w * w * w);
    }
    m[x]++;
    d[i] = x;
  }

  sort(d + 1, d + n + 1);
  n = unique(d + 1, d + n + 1) - d - 1;

  for (int i = 1; i <= n; ++i) {
    ll x = d[i];
    if (m[x] == 0)
      continue;
    if (x == 1) {
      ans++;
      continue;
    }
    ll xa = x, xb = 1;
    for (ll w = 0; w < 430; ++w) {
      ll j = pr[w];
      if (xa % j == 0) {
        int cnt = 0;
        while (xa % j == 0)
          cnt++, xa /= j;
        if (cnt == 1)
          xb *= j * j;
        else
          xb *= j;
      }
    }
    ll y = sqrt(xa);
    if (y * y == xa) {
      xb *= y;
      ans += max(m[x], m[xb]);
      m[x] = m[xb] = 0;
    } else {
      if (xa <= (ll)1e5 && mrt(xa)) {
        xb *= xa * xa;
      } else {
        xb = (ll)1e18;
      }
      ans += max(m[x], m[xb]);
      m[x] = m[xb] = 0;
    }
  }

  cout << ans << endl;

  // cerr << (clock() + 0.0) / 1000.0 << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#include <stdio.h>

using namespace std;

typedef double db;
typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;

typedef pair<db, db> pdd;
typedef pair<db, ld> pdl;
typedef pair<ld, db> pld;
typedef pair<ld, ld> ldp;

typedef pair<ll, ll> pll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<int, int> pii;

#define f first
#define s second

#define en end()
#define bg begin()

#define rev reverse
#define mp make_pair
#define pb push_back

#define y1 y1234567890
#define um unordered_map

#define all(x) x.bg, x.en
#define sz(x) (int)x.size()
#define len(x) (int)strlen(x)

#define sqr(x) ((x + 0ll) * (x))
#define sqrd(x) ((x + 0.0) * (x))

#define forn(i, n) for (int i = 1; i <= n; i++)

const ll inf = (ll)1e18;

const db eps = (db)1e-9;
const db pi = acos(-1.0);

const ll NM = (ll)1e18;
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 300500;

int n;
ll d[N], ans;
map<ll, int> m;
set<ll> s;
vector<ll> pr;

ll mul_mod(ll a, ll b, ll mod) {
  if (NM / a >= b)
    return a * b % mod;
  ll res = 0;
  while (b) {
    if (b & 1)
      res = (res + a) % mod;
    a = (a * 2ll) % mod;
    b >>= 1;
  }
  return res;
}
ll powm(ll p, ll n, ll mod) {
  ll res = 1;
  while (n) {
    if (n & 1)
      res = mul_mod(res, p, mod);
    p = mul_mod(p, p, mod);
    n >>= 1;
  }
  return res;
}
bool mrt(ll p) {
  if (p == 1)
    return false;
  for (int i = 0; i < 430; ++i) {
    ll j = pr[i];
    if (j * j > p)
      break;
    if (p % j == 0)
      return false;
  }
  ll s = 0, d = p - 1;
  while (!(d & 1)) {
    d = d / 2;
    s++;
  }
  srand(time(NULL)); /// Генерируем действительно случайные и разные a
  for (int i = 1; i <= 5; ++i) { /// Те самые 5 проверок
    ll a = rand() % p;
    if (a == 0)
      a++;
    bool flag1 = false, flag2 = false;
    if (powm(a % p, d, p) == 1) /// Первая проверка
      flag1 = true;
    if (!flag1)
      for (int r = 0; r < s; ++r) /// Вторая проверка
        if (powm(a % p, (1LL << r) * d, p) == p - 1)
          flag2 = true;
    if (!flag1 && !flag2)
      return false;
  }
  return true;
}

int main() {
  // freopen(".in", "r", stdin);
  // freopen(".out", "w", stdout);
  // freopen(".err", "w", stderr);

  // srand(time(NULL));

  // cin.tie(NULL);
  // cout.tie(NULL);
  // ios_base::sync_with_stdio(false);

  // cout << setprecision(10) << fixed;

  int n;
  cin >> n;

  for (int i = 2; i <= 3000; ++i) {
    bool ok = 1;
    for (int j = 2; j * j <= i; ++j)
      if (i % j == 0)
        ok = 0;
    if (ok)
      pr.pb(i);
  }

  for (int i = 1; i <= n; ++i) {
    ll x;
    cin >> x;
    // x = (ll)1e10 - i + 1;
    for (ll j = 0; j < 430; ++j) {
      ll w = pr[j];
      while (x % (w * w * w) == 0)
        x /= (w * w * w);
    }
    m[x]++;
    d[i] = x;
  }

  sort(d + 1, d + n + 1);
  n = unique(d + 1, d + n + 1) - d - 1;

  for (int i = 1; i <= n; ++i) {
    ll x = d[i];
    if (m[x] == 0)
      continue;
    if (x == 1) {
      ans++;
      continue;
    }
    ll xa = x, xb = 1;
    for (ll w = 0; w < 430; ++w) {
      ll j = pr[w];
      if (xa % j == 0) {
        int cnt = 0;
        while (xa % j == 0)
          cnt++, xa /= j;
        if (cnt == 1)
          xb *= j * j;
        else
          xb *= j;
      }
    }
    ll y = sqrt(xa);
    if (y * y == xa) {
      xb *= y;
      ans += max(m[x], m[xb]);
      m[x] = m[xb] = 0;
    } else {
      if (xa <= (ll)1e5 && mrt(xa)) {
        xb *= xa * xa;
      } else {
        xb = (ll)1e18;
      }
      ans += max(m[x], m[xb]);
      m[x] = m[xb] = 0;
    }
  }

  cout << ans << endl;

  // cerr << (clock() + 0.0) / 1000.0 << endl;
  return 0;
}