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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for (int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for (int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;

const ll INF = (ll)1e18;
const int BITS = 18;
const int MAX = (1 << 18) + 5;
const int MAX_VAL = 1e5 + 5;
vector<ii> queries[MAX];
ll memo[BITS][MAX_VAL];
vector<int> visited_states[BITS];
vector<int> dfs_stack;
multiset<int> weights;
int v[MAX], w[MAX];
int n, min_weight[BITS];

ll roll(int idx, int limit) {
  if (limit < 0) {
    return -INF;
  }
  if (idx == -1) {
    return 0;
  }
  if (min_weight[idx] > limit) {
    return 0;
  }
  ll &ans = memo[idx][limit];
  if (~ans) {
    return ans;
  }
  visited_states[idx].push_back(limit);
  int node = dfs_stack[idx];
  ans = max(roll(idx - 1, limit), roll(idx - 1, limit - w[node]) + v[node]);
  return ans;
}

ll ans[MAX];
void dfs(int node) {
  if (node > n)
    return;
  weights.insert(w[node]);
  int id = dfs_stack.size();
  dfs_stack.push_back(node);
  min_weight[id] = *weights.begin();
  for (auto &each : queries[node]) {
    int l, idx;
    tie(l, idx) = each;
    ans[idx] = roll(id, l);
  }
  dfs(2 * node);
  dfs(2 * node + 1);
  dfs_stack.pop_back();
  id = dfs_stack.size();
  for (auto &each : visited_states[id])
    memo[id][each] = -1;
  visited_states[id].clear();
  weights.erase(weights.find(w[node]));
}

void solve() {
  scanf("%d", &n);
  fori(i, 1, n + 1) scanf("%d %d", v + i, w + i);
  int q;
  scanf("%d", &q);
  fori(i, 0, q) {
    int k, l;
    scanf("%d %d", &k, &l);
    queries[k].emplace_back(l, i);
  }
  memset(memo, -1, sizeof memo);
  dfs(1);
  fori(i, 0, q) { printf("%lld\\n", ans[i]); }
}

int main() {
  solve();
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for (int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for (int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;

const ll INF = (ll)1e18;
const int BITS = 18;
const int MAX = (1 << 18) + 5;
const int MAX_VAL = 1e5 + 5;
vector<ii> queries[MAX];
ll memo[BITS][MAX_VAL];
vector<int> visited_states[BITS];
vector<int> dfs_stack;
int v[MAX], w[MAX];
int n;

ll roll(int idx, int limit) {
  if (limit < 0) {
    return -INF;
  }
  if (idx == -1) {
    return 0;
  }
  ll &ans = memo[idx][limit];
  if (~ans) {
    return ans;
  }
  visited_states[idx].push_back(limit);
  int node = dfs_stack[idx];
  ans = max(roll(idx - 1, limit), roll(idx - 1, limit - w[node]) + v[node]);
  return ans;
}

ll ans[MAX];
void dfs(int node) {
  if (node > n)
    return;
  int id = dfs_stack.size();
  dfs_stack.push_back(node);
  for (auto &each : queries[node]) {
    int l, idx;
    tie(l, idx) = each;
    ans[idx] = roll(id, l);
  }
  dfs(2 * node);
  dfs(2 * node + 1);
  dfs_stack.pop_back();
  id = dfs_stack.size();
  for (auto &each : visited_states[id])
    memo[id][each] = -1;
  visited_states[id].clear();
}

void solve() {
  scanf("%d", &n);
  fori(i, 1, n + 1) scanf("%d %d", v + i, w + i);
  int q;
  scanf("%d", &q);
  fori(i, 0, q) {
    int k, l;
    scanf("%d %d", &k, &l);
    queries[k].emplace_back(l, i);
  }
  memset(memo, -1, sizeof memo);
  dfs(1);
  fori(i, 0, q) { printf("%lld\\n", ans[i]); }
}

int main() {
  solve();
  return 0;
}