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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef uint64_t u64;
typedef int64_t s64;
typedef uint32_t u32;
typedef int32_t s32;
typedef vector<s32> vs32;
typedef vector<u32> vu32;
typedef vector<s64> vs64;
typedef vector<u64> vu64;

const double PI = 3.14159265358979323846;

#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) > (y) ? (y) : (x))

#define rep(i, N) for (int i = 0; i < N; ++i)

#define CEIL(x, y) (((x) + (y)-1) / (y))
#define MOD 1000000007ULL

#define IN(l, r, x) ((l) <= (x) && (x) < (r))

s64 N, A, B, C, D;
map<s64, s64> m;

s64 dfs(s64 n) {
  if (n == 0)
    return 0;
  if (n == 1)
    return D;
  if (m.count(n) > 0)
    return m[n];

  s64 ret = 1e18;
  if (n < ret / D)
    ret = n * D;
  vs64 temp(6);
  static const s64 div[3] = {2, 3, 5};
  s64 c[3] = {A, B, C};
  rep(i, 3) {
    temp[2 * i] = abs(n - (n / div[i]) * div[i]) * D + c[i] + dfs(n / div[i]);
    temp[2 * i + 1] =
        abs(n - CEIL(n, div[i]) * div[i]) * D + c[i] + dfs(CEIL(n, div[i]));
  }

  rep(i, 6) ret = min(ret, temp[i]);
  m[n] = ret;
  return ret;
}

void solve() {
  cin >> N >> A >> B >> C >> D;

  m.clear();
  cout << dfs(N) << "\\n";
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int t;
  cin >> t;
  rep(CASE, t) { solve(); }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef uint64_t u64;
typedef int64_t s64;
typedef uint32_t u32;
typedef int32_t s32;
typedef vector<s32> vs32;
typedef vector<u32> vu32;
typedef vector<s64> vs64;
typedef vector<u64> vu64;

const double PI = 3.14159265358979323846;

#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) > (y) ? (y) : (x))

#define rep(i, N) for (int i = 0; i < N; ++i)

#define CEIL(x, y) (((x) + (y)-1) / (y))
#define MOD 1000000007ULL

#define IN(l, r, x) ((l) <= (x) && (x) < (r))

s64 N, A, B, C, D;
map<s64, s64> m;
s64 now;

s64 dfs(s64 n, s64 cost) {
  // if (n == 0) return cost;
  if (now <= cost)
    return 1e18;
  if (m[n] && m[n] <= cost)
    return 1e18;
  m[n] = cost;

  // cout << "n, cost, cnt = " << n << ", " << cost << "\\n";
  s64 ret = 1e18;
  vs64 temp(3, 1e18);
  for (s64 i = 0; i <= 5; ++i) {
    s64 nextp = n + i;
    s64 nextm = n - i;
    s64 dc = i * D;
    s64 div[3] = {2, 3, 5};
    s64 c[3] = {A, B, C};
    s64 num;
    s64 cnt;
    rep(j, 3) {
      if (nextp == 0) {
        ret = min(ret, cost + dc);
        break;
      }
      if (nextp % div[j] == 0) {
        num = div[j];
        cnt = 1;
        while (nextp % num == 0) {
          if ((nextp - nextp / num) * D < 0 ||
              (nextp - nextp / num) * D > cnt * c[j]) {
            temp[j] = min(temp[j], dfs(nextp / num, cost + cnt * c[j] + dc));
          } else {
            temp[j] = min(temp[j], dfs(nextp / num,
                                       cost + dc + (nextp - nextp / num) * D));
          }
          ++cnt;
          num *= div[j];
        }
      }
    }
    rep(j, 3) {
      if (nextm < 0)
        break;
      if (nextm == 0) {
        ret = min(ret, cost + dc);
        break;
      }
      if (nextm % div[j] == 0) {
        num = div[j];
        cnt = 1;
        while (nextm % num == 0) {
          if ((abs(nextm) - abs(nextm) / num) * D < 0 ||
              (abs(nextm) - abs(nextm) / num) * D > cnt * c[j]) {
            temp[j] = min(temp[j], dfs(nextm / num, cost + cnt * c[j] + dc));
          } else {
            temp[j] = min(temp[j],
                          dfs(nextm / num,
                              cost + (abs(nextm) - abs(nextm) / num) * D + dc));
          }
          num *= div[j];
          ++cnt;
        }
      }
    }
  }

  rep(i, 3) ret = min(ret, temp[i]);
  // cout << "n, ret: " << n << ", " << ret << "\\n";
  now = min(now, ret);
  m[n] = min(m[n], ret);
  return ret;
}

void solve() {
  cin >> N >> A >> B >> C >> D;

  now = 1e18;
  m.clear();
  cout << dfs(N, 0) << "\\n";
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int t;
  cin >> t;
  rep(CASE, t) { solve(); }

  return 0;
}