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

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <stack>
#include <vector>

using namespace std;

#define MAX 10000003
#define KMAX 1000000000000003LL

vector<int> vprimes;
bool *isPrime = new bool[MAX];

template <typename Integer> Integer GCD(Integer a, Integer b) {
  if (!b)
    return a;
  else
    return GCD(b, a % b);
}

void MakePrime() {
  for (int i = 0; i < MAX; ++i)
    isPrime[i] = true;
  isPrime[0] = false;
  isPrime[1] = false;
  for (long long int i = 2; i < MAX; ++i)
    if (isPrime[i])
      for (long long int j = 2; i * j < MAX; ++j)
        isPrime[i * j] = false;
  for (int i = 0; i < MAX; ++i)
    if (isPrime[i])
      vprimes.push_back(i);
}

template <typename Integer> void Factorization(Integer n, vector<Integer> &vp) {
  if (n == 1) {
    vp.push_back(1);
    return;
  }
  for (int i = 0; i < vprimes.size(); ++i) {
    while (n % vprimes[i] == 0) {
      n /= vprimes[i];
      vp.push_back(vprimes[i]);
    }
    if (n == 1)
      break;
  }
  if (n != 1)
    vp.push_back(n);
}

template <typename Integer>
void Factorization(Integer n, vector<pair<Integer, Integer>> &vp) {
  if (n == 1) {
    vp.push_back(make_pair(1, 1));
    return;
  }
  for (int i = 0; i < vprimes.size(); ++i) {
    while (n % vprimes[i] == 0) {
      n /= vprimes[i];
      if (vp.size() > 0 && vp.back().first == vprimes[i])
        vp.back().second++;
      else
        vp.push_back(make_pair(vprimes[i], 1));
    }
    if (n == 1)
      return;
  }
  vp.push_back(make_pair(n, 1));
}

/* Euler phi */
template <typename Integer> Integer EulerPhi(Integer n) {
  if (n == 0)
    return 0;
  Integer ret = n;
  for (Integer x = 2; x * x <= n; ++x) {
    if (!(n % x)) {
      ret -= ret / x;
      while (!(n % x))
        n /= x;
    }
  }
  if (n > 1)
    ret -= ret / n;
  return ret - 1;
}

// ®ªÌñ,vvÉ½¢µÄÐÆÂÌªvª èAvÌ®Íå«¢ÉÀÔ
void partitions(int n, int max_n, vector<int> &v, vector<vector<int>> &vv) {
  if (n == 0) {
    vv.push_back(v);
    return;
  }
  for (int i = min(n, max_n); i > 0; i--) {
    v.push_back(i);
    partitions(n - i, i, v, vv);
    v.pop_back();
  }
}

// ®ªÌ ( O(nm) ) n ð
// mÂÈºÌ®Åª·é
long long int partitions_num(int n, int m) {
  long long int dp[m + 1][n + 1];
  dp[0][0] = 1;
  for (int i = 1; i <= m; ++i) {
    for (int j = 0; j <= n; ++j) {
      dp[i][j] = dp[i][j - i];
      if (j - i >= 0)
        dp[i][j] += dp[i - 1][j];
    }
  }
  return dp[m][n];
}

// d¡gÝí¹ O(nm)
// a[i]Â éníÞÌàÌ©çvmÉÈéæ¤ÉIñ¾Æ«ÌgÝí¹Ì
long long int dupl_comb(int n, int m, int a[]) {
  long long int dp[n + 1][m + 1];
  for (int i = 0; i <= n; ++i) {
    dp[i][0] = 1;
  }
  for (int i = 0; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      dp[i + 1][j] = dp[i + 1][j - 1] + dp[i][j];
      if (j - 1 - a[i] >= 0)
        dp[i + 1][j] += dp[i][j - 1 - a[i]];
    }
  }
  return dp[n][m];
}

template <typename Integer> Integer divisorFunction1(Integer n) {
  Integer ret = 0;
  if (n == 1)
    return 1;
  stack<pair<Integer, Integer>> st;
  vector<pair<Integer, Integer>> facts;
  Factorization(n, facts);
  st.push(make_pair(0, 1));
  while (!st.empty()) {
    pair<Integer, Integer> nst = st.top();
    st.pop();
    if (nst.first >= facts.size()) {
      ret += nst.second;
      continue;
    }
    Integer r = 1;
    for (int i = 0; i < facts[nst.first].second + 1; ++i) {
      pair<Integer, Integer> nx(nst.first + 1, nst.second * r);
      st.push(nx);
      r *= facts[nst.first].first;
    }
  }
  return ret;
}

static double memo[MAX] = {
    0,
};
static int memo_n[MAX] = {
    0,
};
int main2() {
  MakePrime();
  map<long long int, double> M;
  long long int k = 1;
  while (true) {
    long long int ans_n = -1;
    double ans = -1;
    // cin >> k;
    if (k % 10000 == 0) {
      cout << k << ' ' << M.size() << endl;
    }
    if (k > 1000000)
      break;
    for (long long int n = k; n >= 1; --n) {
      if (memo[n] > 0) {
        if (memo[n] > ans) {
          ans = memo[n];
          ans_n = memo_n[n];
        }
        break;
      }
      long long int sigma = divisorFunction1(n);
      if (ans < (double)sigma / (double)n) {
        ans = (double)sigma / (double)n;
        ans_n = n;
      }
    }
    memo[k] = ans;
    memo_n[k] = ans_n;
    M[ans_n] = ans;
    //    cout << k << ' ' << ans_n << ' ' << ans << endl;
    ++k;
  }
  for (map<long long int, double>::iterator itm = M.begin(); itm != M.end();
       ++itm) {
    vector<pair<long long int, long long int>> facts;
    Factorization(itm->first, facts);
    cout << itm->first << ' ' << itm->second << endl;
    for (int i = 0; i < facts.size(); ++i) {
      cout << facts[i].first << "(" << facts[i].second << ") ";
    }
    cout << endl;
  }
  cout << endl;
  return 0;
}

int main() {
  map<long long int, double> M;
  MakePrime();
  for (int base = 0; base < 2; ++base) {
    for (int n = 1; n < 21; ++n) {
      vector<int> v;
      vector<vector<int>> vv;
      cerr << n << endl;
      partitions(n, 14, v, vv);
      for (int i = 0; i < vv.size(); ++i) {
        long long int llv = 1;
        for (int j = 0; j < vv[i].size(); ++j) {
          for (int k = 0; k < vv[i][j]; ++k) {
            if (llv * vprimes[base + j] > KMAX)
              break;
            llv *= vprimes[base + j];
          }
          if (llv * vprimes[base + j] > KMAX)
            break;
        }
        if (llv > 0 && llv < KMAX) {
          long long int df = divisorFunction1(llv);
          M[llv] = max(M[llv], divisorFunction1(llv) / (double)llv);
        }
      }
    }
  }
  while (true) {
    long long int k;
    double ans = 1;
    cin >> k;
    if (k == 0)
      break;
    if (k == 1)
      ans = 1;
    for (map<long long int, double>::iterator itm = M.begin(); itm != M.end();
         ++itm) {
      if (itm->first <= k) {
        ans = max(ans, itm->second);
      } else
        break;
    }
    printf("%.6lf\\n", ans);
  }
  /*

  MakePrime();
  for(long long int div=1;div<30;++div){
    vector< pair<long long int,long long int> > facts;
    long long int prime=0;
    long long int v=1;
    Factorization(div,facts);
    for(int i = (int)facts.size()-1; i >= 0; --i){
      for(int k = 0; k < facts[i].second; ++k){
        for(int l = 0; l < facts[i].first-1; ++l){
          v*=vprimes[prime];
        }
        ++prime;
      }
    }
    if(v<0||v>KMAX)continue;
    else{
      cout << div << ' ' << v << ' ' << divisorFunction1(v) << endl;
    }
  }
  */
  /*
  MakePrime();
  map<long long int, double> M;
  stack<pair<int,long long int> > st;
  st.push(make_pair(0,2));
  while(!st.empty()){
    pair<int,long long int> now=st.top();st.pop();
    divisorFunction1(now.second)/(double)now.second;
    //cout << now.first << ' ' << now.second << endl;
    long long int r=vprimes[now.first];
    for(int i = 0; ; ++i){
      //cout << now.second * r << endl;
      if(now.second*r>KMAX||now.second*r<now.second)break;
      st.push(make_pair(now.first+1,now.second*r));
      r *= vprimes[now.first];
    }
  }

  while(true){
    int k ;
    cin >> k ;
    if( k == 0 ) break ;

  }
  */
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <stack>
#include <vector>

using namespace std;

#define MAX 10000003
#define KMAX 1000000000000003LL

vector<int> vprimes;
bool *isPrime = new bool[MAX];

template <typename Integer> Integer GCD(Integer a, Integer b) {
  if (!b)
    return a;
  else
    return GCD(b, a % b);
}

void MakePrime() {
  for (int i = 0; i < MAX; ++i)
    isPrime[i] = true;
  isPrime[0] = false;
  isPrime[1] = false;
  for (long long int i = 2; i < MAX; ++i)
    if (isPrime[i])
      for (long long int j = 2; i * j < MAX; ++j)
        isPrime[i * j] = false;
  for (int i = 0; i < MAX; ++i)
    if (isPrime[i])
      vprimes.push_back(i);
}

template <typename Integer> void Factorization(Integer n, vector<Integer> &vp) {
  if (n == 1) {
    vp.push_back(1);
    return;
  }
  for (int i = 0; i < vprimes.size(); ++i) {
    while (n % vprimes[i] == 0) {
      n /= vprimes[i];
      vp.push_back(vprimes[i]);
    }
    if (n == 1)
      break;
  }
  if (n != 1)
    vp.push_back(n);
}

template <typename Integer>
void Factorization(Integer n, vector<pair<Integer, Integer>> &vp) {
  if (n == 1) {
    vp.push_back(make_pair(1, 1));
    return;
  }
  for (int i = 0; i < vprimes.size(); ++i) {
    while (n % vprimes[i] == 0) {
      n /= vprimes[i];
      if (vp.size() > 0 && vp.back().first == vprimes[i])
        vp.back().second++;
      else
        vp.push_back(make_pair(vprimes[i], 1));
    }
    if (n == 1)
      return;
  }
  vp.push_back(make_pair(n, 1));
}

/* Euler phi */
template <typename Integer> Integer EulerPhi(Integer n) {
  if (n == 0)
    return 0;
  Integer ret = n;
  for (Integer x = 2; x * x <= n; ++x) {
    if (!(n % x)) {
      ret -= ret / x;
      while (!(n % x))
        n /= x;
    }
  }
  if (n > 1)
    ret -= ret / n;
  return ret - 1;
}

// ®ªÌñ,vvÉ½¢µÄÐÆÂÌªvª èAvÌ®Íå«¢ÉÀÔ
void partitions(int n, int max_n, vector<int> &v, vector<vector<int>> &vv) {
  if (n == 0) {
    vv.push_back(v);
    return;
  }
  for (int i = min(n, max_n); i > 0; i--) {
    v.push_back(i);
    partitions(n - i, i, v, vv);
    v.pop_back();
  }
}

// ®ªÌ ( O(nm) ) n ð
// mÂÈºÌ®Åª·é
long long int partitions_num(int n, int m) {
  long long int dp[m + 1][n + 1];
  dp[0][0] = 1;
  for (int i = 1; i <= m; ++i) {
    for (int j = 0; j <= n; ++j) {
      dp[i][j] = dp[i][j - i];
      if (j - i >= 0)
        dp[i][j] += dp[i - 1][j];
    }
  }
  return dp[m][n];
}

// d¡gÝí¹ O(nm)
// a[i]Â éníÞÌàÌ©çvmÉÈéæ¤ÉIñ¾Æ«ÌgÝí¹Ì
long long int dupl_comb(int n, int m, int a[]) {
  long long int dp[n + 1][m + 1];
  for (int i = 0; i <= n; ++i) {
    dp[i][0] = 1;
  }
  for (int i = 0; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      dp[i + 1][j] = dp[i + 1][j - 1] + dp[i][j];
      if (j - 1 - a[i] >= 0)
        dp[i + 1][j] += dp[i][j - 1 - a[i]];
    }
  }
  return dp[n][m];
}

template <typename Integer> Integer divisorFunction1(Integer n) {
  Integer ret = 0;
  if (n == 1)
    return 1;
  stack<pair<Integer, Integer>> st;
  vector<pair<Integer, Integer>> facts;
  Factorization(n, facts);
  st.push(make_pair(0, 1));
  while (!st.empty()) {
    pair<Integer, Integer> nst = st.top();
    st.pop();
    if (nst.first >= facts.size()) {
      ret += nst.second;
      continue;
    }
    Integer r = 1;
    for (int i = 0; i < facts[nst.first].second + 1; ++i) {
      pair<Integer, Integer> nx(nst.first + 1, nst.second * r);
      st.push(nx);
      r *= facts[nst.first].first;
    }
  }
  return ret;
}

static double memo[MAX] = {
    0,
};
static int memo_n[MAX] = {
    0,
};
int main2() {
  MakePrime();
  map<long long int, double> M;
  long long int k = 1;
  while (true) {
    long long int ans_n = -1;
    double ans = -1;
    // cin >> k;
    if (k % 10000 == 0) {
      cout << k << ' ' << M.size() << endl;
    }
    if (k > 1000000)
      break;
    for (long long int n = k; n >= 1; --n) {
      if (memo[n] > 0) {
        if (memo[n] > ans) {
          ans = memo[n];
          ans_n = memo_n[n];
        }
        break;
      }
      long long int sigma = divisorFunction1(n);
      if (ans < (double)sigma / (double)n) {
        ans = (double)sigma / (double)n;
        ans_n = n;
      }
    }
    memo[k] = ans;
    memo_n[k] = ans_n;
    M[ans_n] = ans;
    //    cout << k << ' ' << ans_n << ' ' << ans << endl;
    ++k;
  }
  for (map<long long int, double>::iterator itm = M.begin(); itm != M.end();
       ++itm) {
    vector<pair<long long int, long long int>> facts;
    Factorization(itm->first, facts);
    cout << itm->first << ' ' << itm->second << endl;
    for (int i = 0; i < facts.size(); ++i) {
      cout << facts[i].first << "(" << facts[i].second << ") ";
    }
    cout << endl;
  }
  cout << endl;
  return 0;
}

int main() {
  map<long long int, double> M;
  MakePrime();
  for (int base = 0; base < 20; ++base) {
    for (int n = 1; n < 30; ++n) {
      vector<int> v;
      vector<vector<int>> vv;
      // cerr<<n<<endl;
      partitions(n, 14, v, vv);
      for (int i = 0; i < vv.size(); ++i) {
        long long int llv = 1;
        for (int j = 0; j < vv[i].size(); ++j) {
          for (int k = 0; k < vv[i][j]; ++k) {
            if (llv * vprimes[base + j] > KMAX)
              break;
            llv *= vprimes[base + j];
          }
          if (llv * vprimes[base + j] > KMAX)
            break;
        }
        if (llv > 0 && llv < KMAX) {
          long long int df = divisorFunction1(llv);
          M[llv] = max(M[llv], divisorFunction1(llv) / (double)llv);
        }
      }
    }
  }
  while (true) {
    long long int k;
    double ans = 1;
    cin >> k;
    if (k == 0)
      break;
    if (k == 1)
      ans = 1;
    for (map<long long int, double>::iterator itm = M.begin(); itm != M.end();
         ++itm) {
      if (itm->first <= k) {
        ans = max(ans, itm->second);
      } else
        break;
    }
    printf("%.6lf\\n", ans);
  }
  /*

  MakePrime();
  for(long long int div=1;div<30;++div){
    vector< pair<long long int,long long int> > facts;
    long long int prime=0;
    long long int v=1;
    Factorization(div,facts);
    for(int i = (int)facts.size()-1; i >= 0; --i){
      for(int k = 0; k < facts[i].second; ++k){
        for(int l = 0; l < facts[i].first-1; ++l){
          v*=vprimes[prime];
        }
        ++prime;
      }
    }
    if(v<0||v>KMAX)continue;
    else{
      cout << div << ' ' << v << ' ' << divisorFunction1(v) << endl;
    }
  }
  */
  /*
  MakePrime();
  map<long long int, double> M;
  stack<pair<int,long long int> > st;
  st.push(make_pair(0,2));
  while(!st.empty()){
    pair<int,long long int> now=st.top();st.pop();
    divisorFunction1(now.second)/(double)now.second;
    //cout << now.first << ' ' << now.second << endl;
    long long int r=vprimes[now.first];
    for(int i = 0; ; ++i){
      //cout << now.second * r << endl;
      if(now.second*r>KMAX||now.second*r<now.second)break;
      st.push(make_pair(now.first+1,now.second*r));
      r *= vprimes[now.first];
    }
  }

  while(true){
    int k ;
    cin >> k ;
    if( k == 0 ) break ;

  }
  */
  return 0;
}