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

#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include <random>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)

int N;
int V[300000], W[300000];

vector<pair<int, int>> v1[300000], v2[300000];
vector<int> v3[300000];

int Q;
unordered_map<int, vector<pair<int, int>>> query;
int ans[100000];

void solve(int v) {
  if (v < 512) {
    vector<pair<int, int>> tmp1, tmp2;
    rep(j, v1[v >> 1].size()) {
      tmp1.pb(v1[v >> 1][j]);
      tmp2.pb({v1[v >> 1][j].first + W[v], v1[v >> 1][j].second + V[v]});
    }
    int j = 0;
    int k = 0;
    int M = -1;
    while (j < tmp1.size() || k < tmp2.size()) {
      if (v1[v].size() > 0 && v1[v].back().second <= M) {
        v1[v].pop_back();
      }
      if (v1[v].size() > 0)
        M = v1[v].back().second;
      if (j == tmp1.size()) {
        v1[v].pb(tmp2[k]);
        k++;
        continue;
      }
      if (k == tmp2.size()) {
        v1[v].pb(tmp1[j]);
        j++;
        continue;
      }
      if (tmp1[j] < tmp2[k]) {
        v1[v].pb(tmp1[j]);
        j++;
      } else {
        v1[v].pb(tmp2[k]);
        k++;
      }
    }
    v2[v] = v2[v >> 1];
    v3[v] = v3[v >> 1];
  } else {
    v1[v] = v1[v >> 1];
    vector<pair<int, int>> tmp1, tmp2;
    rep(j, v2[v >> 1].size()) {
      tmp1.pb(v2[v >> 1][j]);
      tmp2.pb({v2[v >> 1][j].first + W[v], v2[v >> 1][j].second + V[v]});
    }
    int j = 0;
    int k = 0;
    int M = -1;
    while (j < tmp1.size() || k < tmp2.size()) {
      if (v2[v].size() > 0 && v2[v].back().second <= M) {
        v2[v].pop_back();
      }
      if (v2[v].size() > 0)
        M = v2[v].back().second;
      if (j == tmp1.size()) {
        v2[v].pb(tmp2[k]);
        k++;
        continue;
      }
      if (k == tmp2.size()) {
        v2[v].pb(tmp1[j]);
        j++;
        continue;
      }
      if (tmp1[j] < tmp2[k]) {
        v2[v].pb(tmp1[j]);
        j++;
      } else {
        v2[v].pb(tmp2[k]);
        k++;
      }
    }
    rep(j, v2[v].size()) {
      int x = (v3[v].size() > 0 ? v3[v].back() : 0);
      x = max(x, v2[v][j].second);
      v3[v].pb(x);
    }
  }

  rep(i, query[v].size()) {
    int L = query[v][i].first;
    int _ans = 0;
    int k = v2[v].size() - 1;
    rep(j, v1[v].size()) {
      while (k >= 0 && v2[v][k].first + v1[v][j].first > L) {
        k--;
      }
      if (k == -1)
        break;
      _ans = max(_ans, v1[v][j].second + v3[v][k]);
    }
    ans[query[v][i].second] = _ans;
  }

  if (v * 2 <= N)
    solve(v * 2);
  if (v * 2 + 1 <= N)
    solve(v * 2 + 1);

  v1[v].clear();
  v1[v].shrink_to_fit();
  v2[v].clear();
  v2[v].shrink_to_fit();
  v3[v].clear();
  v3[v].shrink_to_fit();
}

signed main() {
  scanf("%d", &N);
  rep(i, N) scanf("%d%d", V + i + 1, W + i + 1);
  scanf("%d", &Q);
  rep(i, Q) {
    int v, L;
    scanf("%d%d", &v, &L);
    query[v].pb({L, i});
    if (v == 1) {
      if (W[1] <= L)
        ans[i] = V[1];
      else
        ans[i] = 0;
    }
  }

  v1[1].pb({0, 0});
  v1[1].pb({W[1], V[1]});
  v2[1].pb({0, 0});
  v3[1].pb(0);
  if (N >= 2)
    solve(2);
  if (N >= 3)
    solve(3);

  rep(i, Q) { printf("%d\\n", ans[i]); }
}

Error: MLE

Fixed submission:

#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include <random>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)

int N;
int V[300000], W[300000];

vector<pair<int, int>> v1[300000], v2[300000];
vector<int> v3[300000];

int Q;
unordered_map<int, vector<pair<int, int>>> query;
int ans[100000];

void solve(int v) {
  if (v < 512) {
    vector<pair<int, int>> tmp1, tmp2;
    rep(j, v1[v >> 1].size()) {
      tmp1.pb(v1[v >> 1][j]);
      tmp2.pb({v1[v >> 1][j].first + W[v], v1[v >> 1][j].second + V[v]});
    }
    int j = 0;
    int k = 0;
    int M = -1;
    while (j < tmp1.size() || k < tmp2.size()) {
      if (v1[v].size() > 0 && v1[v].back().second <= M) {
        v1[v].pop_back();
      }
      if (v1[v].size() > 0)
        M = v1[v].back().second;
      if (j == tmp1.size()) {
        v1[v].pb(tmp2[k]);
        k++;
        continue;
      }
      if (k == tmp2.size()) {
        v1[v].pb(tmp1[j]);
        j++;
        continue;
      }
      if (tmp1[j] < tmp2[k]) {
        v1[v].pb(tmp1[j]);
        j++;
      } else {
        v1[v].pb(tmp2[k]);
        k++;
      }
    }
    v2[v] = v2[v >> 1];
    v3[v] = v3[v >> 1];
  } else {
    v1[v] = v1[v >> 1];
    vector<pair<int, int>> tmp1, tmp2;
    rep(j, v2[v >> 1].size()) {
      tmp1.pb(v2[v >> 1][j]);
      tmp2.pb({v2[v >> 1][j].first + W[v], v2[v >> 1][j].second + V[v]});
    }
    int j = 0;
    int k = 0;
    int M = -1;
    while (j < tmp1.size() || k < tmp2.size()) {
      if (v2[v].size() > 0 && v2[v].back().second <= M) {
        v2[v].pop_back();
      }
      if (v2[v].size() > 0)
        M = v2[v].back().second;
      if (j == tmp1.size()) {
        v2[v].pb(tmp2[k]);
        k++;
        continue;
      }
      if (k == tmp2.size()) {
        v2[v].pb(tmp1[j]);
        j++;
        continue;
      }
      if (tmp1[j] < tmp2[k]) {
        v2[v].pb(tmp1[j]);
        j++;
      } else {
        v2[v].pb(tmp2[k]);
        k++;
      }
    }
    rep(j, v2[v].size()) {
      int x = (v3[v].size() > 0 ? v3[v].back() : 0);
      x = max(x, v2[v][j].second);
      v3[v].pb(x);
    }
  }

  rep(i, query[v].size()) {
    int L = query[v][i].first;
    int _ans = 0;
    int k = v2[v].size() - 1;
    rep(j, v1[v].size()) {
      while (k >= 0 && v2[v][k].first + v1[v][j].first > L) {
        k--;
      }
      if (k == -1)
        break;
      _ans = max(_ans, v1[v][j].second + v3[v][k]);
    }
    ans[query[v][i].second] = _ans;
  }

  if (v * 2 <= N)
    solve(v * 2);
  if (v * 2 + 1 <= N)
    solve(v * 2 + 1);

  v1[v].clear();
  v2[v].clear();
  v3[v].clear();
}

signed main() {
  scanf("%d", &N);
  rep(i, N) scanf("%d%d", V + i + 1, W + i + 1);
  scanf("%d", &Q);
  rep(i, Q) {
    int v, L;
    scanf("%d%d", &v, &L);
    query[v].pb({L, i});
    if (v == 1) {
      if (W[1] <= L)
        ans[i] = V[1];
      else
        ans[i] = 0;
    }
  }

  v1[1].pb({0, 0});
  v1[1].pb({W[1], V[1]});
  v2[1].pb({0, 0});
  v3[1].pb(0);
  if (N >= 2)
    solve(2);
  if (N >= 3)
    solve(3);

  rep(i, Q) { printf("%d\\n", ans[i]); }
}