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

#include <bits/stdc++.h>
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pli pair<ll, int>
#define pil pair<int, ll>
#define fi first
#define se second
#define inf (INT_MAX / 2 - 1)
#define infl (1LL << 60)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) (int)(a).size()
#define all(a) begin(a), end(a)
#define y0 y5656
#define y1 y7878
#define aaa system("pause");
#define dbg(x) cerr << (#x) << ": " << (x) << '\\n', aaa
#define dbga(x, n)                                                             \\
  cerr << (#x) << "[]: ";                                                      \\
  for (int _ = 0; _ < n; _++)                                                  \\
    cerr << x[_] << ' ';                                                       \\
  cerr << '\\n', aaa
#define dbgs(x)                                                                \\
  cerr << (#x) << "[stl]: ";                                                   \\
  for (auto _ : x)                                                             \\
    cerr << _ << ' ';                                                          \\
  cerr << '\\n', aaa
#define dbgp(x) cerr << (#x) << ": " << x.fi << ' ' << x.se << '\\n', aaa

using namespace std;

const int maxn = (1 << 18), maxq = 100000, spr = (1 << 9);
int v[maxn + 5], w[maxn + 5], d[maxq + 5][spr + 5], dep[maxn + 5], lg[maxn + 5],
    nod[maxq + 5], l[maxq + 5];
pii ds[spr + 5];

/// d[w][nod] = valoare maxima pt lant nod, greutate = w
///!! nod se afla in PRIMA jumatate a adancimii arborelui binar
///-- SMEN SPRANCEANA GROASA
/// faci asa: rucsac traditional pentru prima jumatate a adancimii
/// si completezi cu dinamica pe stari pentru ultima jumatate (O(2^sz)!! nu
/// O(sz*2^sz)) asa ai aceeasi complexitate pe ambele jumatati

void umax(int &a, int b) { a = max(a, b); }

int lsb(int x) { return x & (-x); }

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  int i, j, z;
  for (i = 2; i <= maxn; i++)
    lg[i] = lg[i >> 1] + 1; ///!!e de la DOI nu UNU
  for (i = 1; i <= n; i++)
    cin >> v[i] >> w[i];
  int md = lg[n] / 2 + 1, q, nn, ml = 0;
  cin >> q; ///<-- +1 de la md daunator? NU, gresisei lg...
  for (i = 1; i <= q; i++) {
    cin >> nod[i] >> l[i];
    umax(ml, l[i]);
  }
  for (i = 1; i <= n; i++) {
    dep[i] = dep[i >> 1] + 1;
    if (dep[i] <= md) {
      for (z = 1; z <= ml; z++)
        d[z][i] = d[z][i >> 1];
      for (z = ml; z >= w[i]; z--)
        umax(d[z][i], d[z - w[i]][i] + v[i]);
      for (z = 1; z <= ml; z++)
        umax(d[z][i], d[z - 1][i]);
    }
  }
  vi u;
  for (z = 1; z <= q; z++) {
    nn = nod[z];
    u.clear();
    while (dep[nn] > md) {
      u.pb(nn);
      nn >>= 1;
    }
    fill(ds, ds + (1 << sz(u)), pii(0, 0));
    int ans = 0, conf;
    for (conf = 0; conf < 1 << sz(u); conf++) {
      i = conf - lsb(conf); /// lsb sau dfs ca sa scapi de sz din O(sz*2^sz)
      j = (conf ? u[lg[lsb(conf)]] : 0); /// fara -1
      ds[conf] = pii(ds[i].fi + v[j], ds[i].se + w[j]);
      if (ds[conf].se <= l[z])
        umax(ans, ds[conf].fi + d[l[z] - ds[conf].se][nn]);
    }
    cout << ans << '\\n';
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pli pair<ll, int>
#define pil pair<int, ll>
#define fi first
#define se second
#define inf (INT_MAX / 2 - 1)
#define infl (1LL << 60)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) (int)(a).size()
#define all(a) begin(a), end(a)
#define y0 y5656
#define y1 y7878
#define aaa system("pause");
#define dbg(x) cerr << (#x) << ": " << (x) << '\\n', aaa
#define dbga(x, n)                                                             \\
  cerr << (#x) << "[]: ";                                                      \\
  for (int _ = 0; _ < n; _++)                                                  \\
    cerr << x[_] << ' ';                                                       \\
  cerr << '\\n', aaa
#define dbgs(x)                                                                \\
  cerr << (#x) << "[stl]: ";                                                   \\
  for (auto _ : x)                                                             \\
    cerr << _ << ' ';                                                          \\
  cerr << '\\n', aaa
#define dbgp(x) cerr << (#x) << ": " << x.fi << ' ' << x.se << '\\n', aaa

using namespace std;

const int maxn = (1 << 18), maxq = 100000, spr = (1 << 9);
int v[maxn + 5], w[maxn + 5], d[maxq + 5][spr + 5], dep[maxn + 5], lg[maxn + 5],
    nod[maxq + 5], l[maxq + 5];
pii ds[spr + 5];

/// d[w][nod] = valoare maxima pt lant nod, greutate = w
///!! nod se afla in PRIMA jumatate a adancimii arborelui binar
///-- SMEN SPRANCEANA GROASA
/// faci asa: rucsac traditional pentru prima jumatate a adancimii
/// si completezi cu dinamica pe stari pentru ultima jumatate (O(2^sz)!! nu
/// O(sz*2^sz)) asa ai aceeasi complexitate pe ambele jumatati

void umax(int &a, int b) { a = max(a, b); }

int lsb(int x) { return x & (-x); }

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  int i, j, z, k;
  for (i = 1; i <= maxn; i++)
    lg[i] = lg[i >> 1] + 1;
  int md = lg[n] / 2 + 1;
  for (i = 1; i <= n; i++)
    cin >> v[i] >> w[i];
  int q, nn, ml = 0;
  cin >> q;
  for (i = 1; i <= q; i++) {
    cin >> nod[i] >> l[i];
    umax(ml, l[i]);
  }
  for (i = 1; i <= n; i++) {
    dep[i] = dep[i >> 1] + 1;
    if (dep[i] <= md) {
      for (k = 0, j = i; j > 0; j >>= 1)
        k += w[j];
      k = min(k, ml); ///<--
      for (z = 1; z <= ml; z++)
        d[z][i] = -inf; /// NU pune maxq.. O(???)
      for (j = i; j > 0; j >>= 1)
        for (z = k; z >= w[j]; z--)
          umax(d[z][i], d[z - w[j]][i] + v[j]);
      ///!!^w[j] nu w[i], d[z-w[j]][i] nu d[z-w[j]][j]
      for (z = 1; z <= ml; z++)
        umax(d[z][i], d[z - 1][i]);
    }
  }
  vi u;
  for (z = 1; z <= q; z++) {
    nn = nod[z];
    u.clear();
    while (dep[nn] > md) {
      u.pb(nn);
      nn >>= 1;
    }
    fill(ds, ds + (1 << sz(u)), pii(0, 0));
    int ans = 0, conf;
    for (conf = 0; conf < 1 << sz(u); conf++) {
      i = conf - lsb(conf); /// lsb sau dfs ca sa scapi de sz din O(sz*2^sz)
      j = (conf ? u[lg[lsb(conf)] - 1] : 0);
      ds[conf] = pii(ds[i].fi + v[j], ds[i].se + w[j]);
      if (ds[conf].se <= l[z])
        umax(ans, ds[conf].fi + d[l[z] - ds[conf].se][nn]);
    }
    cout << ans << '\\n';
  }
  return 0;
}