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

#include <bits/stdc++.h>
using namespace std;

#define li long long int
#define rep(i, to) for (li i = 0; i < ((li)(to)); i++)
#define repp(i, start, to) for (li i = (li)(start); i < ((li)(to)); i++)
#define pb push_back
#define sz(v) ((li)(v).size())
#define bgn(v) ((v).begin())
#define eend(v) ((v).end())
#define allof(v) (v).begin(), (v).end()
#define dodp(v, n) memset(v, (li)n, sizeof(v))
#define bit(n) (1ll << (li)(n))
#define mp(a, b) make_pair(a, b)
#define rin rep(i, n)
#define EPS 1e-12
#define ETOL 1e-8
#define MOD 1000000007
typedef pair<li, li> PI;

#define INF bit(60)

#define DBGP 1

#define idp if (DBGP)
#define F first
#define S second
#define p2(a, b) idp cout << a << "\\t" << b << endl
#define p3(a, b, c) idp cout << a << "\\t" << b << "\\t" << c << endl
#define p4(a, b, c, d)                                                         \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << endl
#define p5(a, b, c, d, e)                                                      \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << endl
#define p6(a, b, c, d, e, f)                                                   \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << endl
#define p7(a, b, c, d, e, f, g)                                                \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << endl
#define p8(a, b, c, d, e, f, g, h)                                             \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << "\\t" << h << endl
#define p9(a, b, c, d, e, f, g, h, i)                                          \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << "\\t" << h << "\\t" << i << endl
#define p10(a, b, c, d, e, f, g, h, i, j)                                      \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << "\\t" << h << "\\t" << i << "\\t" << j << endl
#define foreach(it, v)                                                         \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
#define p2p(x) idp p2((x).F, (x).S)
#define dump(x, n)                                                             \\
  idp {                                                                        \\
    rep(i, n) { cout << x[i] << " "; }                                         \\
    puts("");                                                                  \\
  }
#define dump2(x, n)                                                            \\
  idp {                                                                        \\
    rep(i, n) { cout << "[" << x[i].F << " , " << x[i].S << "] "; }            \\
    puts("");                                                                  \\
  }
#define dumpi(x)                                                               \\
  idp {                                                                        \\
    foreach (it, x) {                                                          \\
      cout << (*it) << " ";                                                    \\
    }                                                                          \\
    puts("");                                                                  \\
  }
#define dumpi2(x)                                                              \\
  idp {                                                                        \\
    foreach (it, x) {                                                          \\
      cout << "[" << (it)->F << " , " << (it)->S << "] ";                      \\
    }                                                                          \\
    puts("");                                                                  \\
  }

#define read2d(a, w, h) rep(i, h) rep(j, w) cin >> a[i][j]
#define dump2d(a, w, h)                                                        \\
  rep(i, h) {                                                                  \\
    rep(j, w) cout << a[i][j] << " ";                                          \\
    puts("");                                                                  \\
  }

typedef pair<li, li> PI;

li v[300300];
li w[300300];
li n;

li memo[555][100100];

inline map<li, li> gen(vector<li> &x, li from, li to, li lim) {
  // 重さxでの最大価値
  map<li, li> res;
  res[0] = 0;
  repp(i, from, to) {
    map<li, li> tmp = res;
    for (auto &&kv : res) {
      li ww = kv.F;
      li vv = kv.S;

      if (ww + w[x[i]] > lim) {
        continue;
      }
      li nw = ww + w[x[i]];
      li nv = vv + v[x[i]];
      tmp[nw] = max(tmp[nw], nv);
    }
    res = tmp;
  }
  li ma = 0;
  for (auto &kv : res) {
    ma = max(kv.S, ma);
    kv.S = ma;
  }
  return res;
}

inline li dfs(li now, li sum_v, li sum_w, li lim) {
  if (sum_w > lim) {
    return 0;
  }
  if (now < 512) {
    return memo[now][lim - sum_w] + sum_v;
  }
  li parent = (now - 1) / 2;
  return max(dfs(parent, sum_v, sum_w, lim),
             dfs(parent, sum_v + v[now], sum_w + w[now], lim));
}

inline li solve() {
  li vv, l;
  cin >> vv >> l;
  vv--;
  li vvv = vv;
  if (vv == 0) {
    return (l >= w[0] ? v[0] : 0ll);
  }
  vector<li> nodes;
  while (vv >= 512) {
    nodes.pb(vv);
    vv = (vv - 1) / 2;
  }
  if (nodes.empty()) {
    return memo[vvv][l];
  }
  auto m1 = gen(nodes, 0, sz(nodes) / 2, l);
  return dfs(vvv, 0, 0, l);
}

int main() {
  cin >> n;
  rin { cin >> v[i] >> w[i]; }
  rep(i, 100001) { memo[0][i] = 0; }
  repp(i, w[0], 100001) { memo[0][i] = v[0]; }
  repp(i, 1, min(512ll, n)) {
    li parent = (i - 1) / 2;
    rep(j, 100001) {
      memo[i][j] = memo[parent][j];
      if (j >= w[i]) {
        memo[i][j] = max(memo[i][j], memo[parent][j - w[i]] + v[i]);
      }
    }
  }
  li q;
  cin >> q;
  rep(i, q) { cout << solve() << endl; }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define li long long int
#define rep(i, to) for (li i = 0; i < ((li)(to)); i++)
#define repp(i, start, to) for (li i = (li)(start); i < ((li)(to)); i++)
#define pb push_back
#define sz(v) ((li)(v).size())
#define bgn(v) ((v).begin())
#define eend(v) ((v).end())
#define allof(v) (v).begin(), (v).end()
#define dodp(v, n) memset(v, (li)n, sizeof(v))
#define bit(n) (1ll << (li)(n))
#define mp(a, b) make_pair(a, b)
#define rin rep(i, n)
#define EPS 1e-12
#define ETOL 1e-8
#define MOD 1000000007
typedef pair<li, li> PI;

#define INF bit(60)

#define DBGP 1

#define idp if (DBGP)
#define F first
#define S second
#define p2(a, b) idp cout << a << "\\t" << b << endl
#define p3(a, b, c) idp cout << a << "\\t" << b << "\\t" << c << endl
#define p4(a, b, c, d)                                                         \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << endl
#define p5(a, b, c, d, e)                                                      \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << endl
#define p6(a, b, c, d, e, f)                                                   \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << endl
#define p7(a, b, c, d, e, f, g)                                                \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << endl
#define p8(a, b, c, d, e, f, g, h)                                             \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << "\\t" << h << endl
#define p9(a, b, c, d, e, f, g, h, i)                                          \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << "\\t" << h << "\\t" << i << endl
#define p10(a, b, c, d, e, f, g, h, i, j)                                      \\
  idp cout << a << "\\t" << b << "\\t" << c << "\\t" << d << "\\t" << e << "\\t"    \\
           << f << "\\t" << g << "\\t" << h << "\\t" << i << "\\t" << j << endl
#define foreach(it, v)                                                         \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
#define p2p(x) idp p2((x).F, (x).S)
#define dump(x, n)                                                             \\
  idp {                                                                        \\
    rep(i, n) { cout << x[i] << " "; }                                         \\
    puts("");                                                                  \\
  }
#define dump2(x, n)                                                            \\
  idp {                                                                        \\
    rep(i, n) { cout << "[" << x[i].F << " , " << x[i].S << "] "; }            \\
    puts("");                                                                  \\
  }
#define dumpi(x)                                                               \\
  idp {                                                                        \\
    foreach (it, x) {                                                          \\
      cout << (*it) << " ";                                                    \\
    }                                                                          \\
    puts("");                                                                  \\
  }
#define dumpi2(x)                                                              \\
  idp {                                                                        \\
    foreach (it, x) {                                                          \\
      cout << "[" << (it)->F << " , " << (it)->S << "] ";                      \\
    }                                                                          \\
    puts("");                                                                  \\
  }

#define read2d(a, w, h) rep(i, h) rep(j, w) cin >> a[i][j]
#define dump2d(a, w, h)                                                        \\
  rep(i, h) {                                                                  \\
    rep(j, w) cout << a[i][j] << " ";                                          \\
    puts("");                                                                  \\
  }

typedef pair<li, li> PI;

li v[300300];
li w[300300];
li n;

li memo[555][100100];

inline map<li, li> gen(vector<li> &x, li from, li to, li lim) {
  // 重さxでの最大価値
  map<li, li> res;
  res[0] = 0;
  repp(i, from, to) {
    map<li, li> tmp = res;
    for (auto &&kv : res) {
      li ww = kv.F;
      li vv = kv.S;

      if (ww + w[x[i]] > lim) {
        continue;
      }
      li nw = ww + w[x[i]];
      li nv = vv + v[x[i]];
      tmp[nw] = max(tmp[nw], nv);
    }
    res = tmp;
  }
  li ma = 0;
  for (auto &kv : res) {
    ma = max(kv.S, ma);
    kv.S = ma;
  }
  return res;
}

inline li solve() {
  li vv, l;
  cin >> vv >> l;
  vv--;
  if (vv == 0) {
    return (l >= w[0] ? v[0] : 0ll);
  }
  vector<li> nodes;
  while (vv != 0) {
    nodes.pb(vv);
    vv = (vv - 1) / 2;
  }
  nodes.pb(0);
  auto m1 = gen(nodes, 0, sz(nodes) / 2, l);
  auto &m2 = memo[nodes[sz(nodes) / 2]];

  li res = 0;
  auto it1 = m1.begin();
  // auto it2 = m2.rbegin();
  /*
  puts("---");
  dumpi(nodes);
  for (auto nn : nodes) {
      cout << " [ " << v[nn] << ", " << w[nn] << " ], ";
  } cout << endl;
  dumpi2(m1);
  dumpi2(m2);
  //*/
  /*
  while (it1 != m1.end()) {
      while (it2 != m2.rend() && it1->F + it2->F > l) {
          it2++;
      }
      if (it2 == m2.rend()) {
          break;
      }
      //p3(it1->F, it2->F, it1->S + it2->S);
      res = max(res, it1->S + it2->S);
      it1++;
  }
  */
  for (auto &&kv : m1) {
    if (kv.F > l) {
      break;
    }
    res = max(res, kv.S + m2[l - kv.F]);
  }
  return res;
}

int main() {
  cin >> n;
  rin { cin >> v[i] >> w[i]; }
  rep(i, 100001) { memo[0][i] = 0; }
  repp(i, w[0], 100001) { memo[0][i] = v[0]; }
  repp(i, 1, min(512ll, n)) {
    li parent = (i - 1) / 2;
    rep(j, 100001) {
      memo[i][j] = memo[parent][j];
      if (j >= w[i]) {
        memo[i][j] = max(memo[i][j], memo[parent][j - w[i]] + v[i]);
      }
    }
  }
  li q;
  cin >> q;
  rep(i, q) { cout << solve() << endl; }

  return 0;
}