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

/*
 * Since g++10 is released, some characters is not valid inside #if 0 :(
 * So, why not using clang++? :D

 * Date:
  echo -n '  ' && date +%Y.%m.%d # Just Run this (Type !!sh in Vim).

 * Solution:
  To be updated after "Accept".

 * Digression:

 * CopyRight:
          ▁▃▄▄▄▃▃▃▃▄▶
        ▗▇▀▔    ▔▔▔▔
       ▄▛   ▃▅━━■▄▂
      ▟▊   ▐▘     ▀▙
     ▟▜▌   ▐▖   ▋  ▐▍
    ▟▘ ▜   ▝▀▇▆●▘  ▐▌
  ▗▟▘   ▜▃       ▁▅▛
  ▔▀▼▅▄▃▃██▅▄▄▄▅■▀▔
        ▔▔▔▔▔▔
 */

#include <algorithm>
#include <cstdio>
#include <vector>
#define debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long ll;

struct {
  inline operator int() {
    int x;
    return scanf("%d", &x), x;
  }
  /* inline operator ll () { ll x; return scanf("%lld", &x), x; } */
  template <class T> inline void operator()(T &x) { x = *this; }
  template <class T, class... A> inline void operator()(T &x, A &...a) {
    x = *this;
    this->operator()(a...);
  }
} read;

const int maxn = 270000, maxw = 100005;
int val[maxn], wei[maxn], dep[maxn];
ll f[515][maxw];
int tv[20], tw[20];

int main() {
  int n = read;
  for (int i = 1; i <= n; i++)
    read(val[i], wei[i]);

  for (int i = 1; i <= n; i++)
    dep[i] = dep[i >> 1] + 1;

  int K = dep[n] >> 1, Lim = 100000;
  for (int i = 1; i <= n and dep[i] <= K; i++) {
    std::copy(f[i >> 1], f[i >> 1] + wei[i], f[i]);
    for (int w = wei[i]; w <= Lim; w++)
      f[i][w] = std::max(f[i >> 1][w], f[i >> 1][w - wei[i]] + val[i]);
  }

  int q = read;
  while (q--) {
    int u = read, lim = read;
    if (dep[u] <= K) {
      printf("%lld\\n", f[u][lim]);
      continue;
    }
    int p = dep[u] - K, x = u >> p;
    for (int i = 0; i < p; i++)
      tv[i] = val[u >> i], tw[i] = wei[u >> i];
    ll ans = 0;
    for (int S = 0; S < (1 << p); S++) {
      ll v = 0, w = 0;
      for (int i = 0; i < p; i++)
        if (S >> i & 1)
          v += tv[i], w += tw[i];
      if (w <= lim)
        ans = std::max(ans, f[x][lim - w] + v);
    }
    printf("%lld\\n", ans);
  }
}


Error: TLE

Fixed submission:

/*
 * Since g++10 is released, some characters is not valid inside #if 0 :(
 * So, why not using clang++? :D

 * Date:
  echo -n '  ' && date +%Y.%m.%d # Just Run this (Type !!sh in Vim).

 * Solution:
  To be updated after "Accept".

 * Digression:

 * CopyRight:
          ▁▃▄▄▄▃▃▃▃▄▶
        ▗▇▀▔    ▔▔▔▔
       ▄▛   ▃▅━━■▄▂
      ▟▊   ▐▘     ▀▙
     ▟▜▌   ▐▖   ▋  ▐▍
    ▟▘ ▜   ▝▀▇▆●▘  ▐▌
  ▗▟▘   ▜▃       ▁▅▛
  ▔▀▼▅▄▃▃██▅▄▄▄▅■▀▔
        ▔▔▔▔▔▔
 */

#include <algorithm>
#include <cstdio>
#include <vector>
#define debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long ll;
typedef std::pair<int, ll> par;

struct {
  inline operator int() {
    int x;
    return scanf("%d", &x), x;
  }
  /* inline operator ll () { ll x; return scanf("%lld", &x), x; } */
  template <class T> inline void operator()(T &x) { x = *this; }
  template <class T, class... A> inline void operator()(T &x, A &...a) {
    x = *this;
    this->operator()(a...);
  }
} read;

const int maxn = 270000, maxk = 10;
int val[maxn], wei[maxn], dep[maxn];
int len[maxn];
std::vector<par> up[maxk][maxn];
par tmp[maxn];

int main() {
  int n = read;
  for (int i = 1; i <= n; i++)
    read(val[i], wei[i]);

  int Lim = 100000;
  up[0][0].push_back(par(0, 0));
  for (int i = 1; i <= n; i++) {
    dep[i] = dep[i >> 1] + 1;
    if (dep[i] <= 9)
      len[i] = dep[i];
    else
      len[i] = dep[i] >> 1;
    up[0][i].push_back(par(0, 0));
    for (int k = 1; k <= len[i]; k++) {
      std::vector<par> a = up[k - 1][i >> 1], b;
      for (par p : up[k - 1][i >> 1])
        if (p.first + wei[i] <= Lim)
          b.push_back(par(p.first + wei[i], p.second + val[i]));
      int tp =
          int(std::merge(a.begin(), a.end(), b.begin(), b.end(), tmp) - tmp);
      up[k][i] = std::vector<par>(tmp, tmp + tp);
    }
  }

  for (int i = 1; i <= n; i++)
    for (int k = 1; k <= len[i]; k++)
      for (size_t j = 1; j < up[k][i].size(); j++)
        up[k][i][j].second =
            std::max(up[k][i][j].second, up[k][i][j - 1].second);

  for (int i = 1; i <= n; i++)
    for (int k = 0; k <= len[i]; k++)
      if (up[k][i].empty())
        return 0;

  int q = read;
  while (q--) {
    int u = read, lim = read;
    int k1 = dep[u] >> 1, k2 = dep[u] - k1;
    int v = u >> k1;
    size_t j = up[k1][u].size() - 1;
    ll ans = 0;
    for (par p : up[k2][v]) {
      while (j and up[k1][u][j].first > lim - p.first)
        --j;
      /* debug("%d %lld | %d %lld | %lu\\n", */
      /* 		p.first, p.second, up[k1][u][j].first,
       * up[k1][u][j].second, j); */
      if (p.first + up[k1][u][j].first <= lim)
        ans = std::max(ans, p.second + up[k1][u][j].second);
    }
    printf("%lld\\n", ans);
  }
}