Problem p02660 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

#include <random>

using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL

// 素数判定
vector<int> pr = {2, 3, 5, 7};

bool isprime(int n) {
  int i;
  int prime(int);
  int sz = pr.size();
  int sq = sqrt(n);
  for (i = 1; i < sz; i++) {
    int p = pr[i];
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
  for (;; i++) {
    int p = prime(i);
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
}

// 素数生成
int prime(int n) {
  int last = pr.size();
  if (n < last)
    return pr[n];

  for (int p = pr.back() + 2; last <= n; p += 2) {
    if (isprime(p)) {
      last++;
      pr.push_back(p);
    }
  }
  return pr.back();
}

// 素因数分解
// 引数の整数を素因数分解する。
// mapクラスのキーに基数、対応する値に指数が入っている
map<ll, int> lc;
map<ll, int> fact(ll n) {
  map<ll, int> ret;
  ll base;
  int ix;

  int i;
  for (i = 0; n > 1; i++) {
    base = prime(i);
    ix = 0;
    while (n % base == 0) {
      ix++;
      n /= base;
    }
    if (ix > 0) {
      ret[base] = ix;
      auto itr = lc.find(base);
      if (itr == lc.end()) {
        lc[base] = ix;
      } else {
        lc[base] = max(ix, lc[base]);
      }
    } else {
      if (base * base >= n) {
        ret[n] = 1;
        auto itr = lc.find(n);
        if (itr == lc.end()) {
          lc[n] = 1;
        } else {
          lc[n] = max(1, lc[n]);
        }
        break;
      }
    }
  }
  return ret;
}

ll n;

ll ipow(int x, int y) {
  ll ret = 1;
  for (int i = 0; i < y; i++) {
    ret *= x;
  }
  return ret;
}

uint32_t rd();

int main() {
  ll ans = 0;
  map<ll, int> f;

  cin >> n;

  f = fact(n);

  for (auto it = f.begin(); it != f.end(); it++) {
    int r;
    r = sqrt(it->second);
    while (r * r + r <= it->second * 2)
      r++;
    r--;
    ans += r;
  }

  cout << ans << endl;
  return 0;
}

uint32_t rd() {
  random_device seed_gen;
  minstd_rand engine(seed_gen());
  return engine();
}

/*
  素数pと正の整数eで z=p^e となるzを選ぶ
  Nがzで割り切れる
  以前の操作で選んだどの整数とも異なる
  */


Error: TLE

Fixed submission:

#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL

// 素数判定
vector<int> pr = {2, 3, 5, 7};

bool isprime(int n) {
  int i;
  int prime(int);
  int sz = pr.size();
  int sq = sqrt(n);
  for (i = 1; i < sz; i++) {
    int p = pr[i];
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
  for (;; i++) {
    int p = prime(i);
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
}

// 素数生成
int prime(int n) {
  int last = pr.size();
  if (n < last)
    return pr[n];

  for (int p = pr.back() + 2; last <= n; p += 2) {
    if (isprime(p)) {
      last++;
      pr.push_back(p);
    }
  }
  return pr.back();
}

// 素因数分解
// 引数の整数を素因数分解する。
// mapクラスのキーに基数、対応する値に指数が入っている
map<int, int> lc;
map<int, int> fact(ll n) {
  map<int, int> ret;
  int base, ix;

  int i;
  for (i = 0; n > 1; i++) {
    base = prime(i);
    ix = 0;
    while (n % base == 0) {
      ix++;
      n /= base;
    }
    if (ix > 0) {
      ret[base] = ix;
      auto itr = lc.find(base);
      if (itr == lc.end()) {
        lc[base] = ix;
      } else {
        lc[base] = max(ix, lc[base]);
      }
    } else {
      if (base * base >= n) {
        ret[n] = 1;
        auto itr = lc.find(n);
        if (itr == lc.end()) {
          lc[n] = 1;
        } else {
          lc[n] = max(1, lc[n]);
        }
        break;
      }
    }
  }
  return ret;
}

ll n;

ll ipow(int x, int y) {
  ll ret = 1;
  for (int i = 0; i < y; i++) {
    ret *= x;
  }
  return ret;
}

int main() {
  ll ans = 0;
  map<int, int> f;

  cin >> n;

  f = fact(n);
  for (auto it = f.begin(); it != f.end(); it++) {
    int r;
    r = sqrt(it->second);
    while (r * r + r <= it->second * 2)
      r++;
    r--;
    ans += r;
  }

  cout << ans << endl;
  return 0;
}

/*
  素数pと正の整数eで z=p^e となるzを選ぶ
  Nがzで割り切れる
  以前の操作で選んだどの整数とも異なる
  */