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

#include "bits/stdc++.h"
using namespace std;
typedef int li;

li n;
vector<li> vs, wes;

vector<li> ans;
map<li, vector<pair<li, li>>> queries;
set<li> need_to_visit;

set<pair<li, li>> clean_set(const set<pair<li, li>> &orig) {
  set<pair<li, li>> ret;
  li maxv = -1;
  for (auto &&item : orig) {
    if (item.second > maxv) {
      maxv = item.second;
      ret.insert(item);
    }
  }
  return ret;
}

li solve(const set<pair<li, li>> &first_half,
         const vector<pair<li, li>> &second_half, const li l) {
  li maxv = 0;
  for (auto &&item : second_half) {
    const li rem = l - item.first;
    if (rem >= 0) {
      auto ptr = first_half.lower_bound(make_pair(rem + 1, -1));
      ptr--;
      maxv = max(maxv, item.second + ptr->second);
    }
  }
  return maxv;
}

void dfs(const li pos, const set<pair<li, li>> &first_half,
         const vector<pair<li, li>> &second_half) {
  if (need_to_visit.find(pos) == need_to_visit.end()) {
    return;
  }

  const bool is_first = pos < 2048;

  if (is_first) {
    set<pair<li, li>> new_comb;
    new_comb = first_half;
    for (auto &&p : first_half) {
      new_comb.emplace(p.first + wes[pos - 1], p.second + vs[pos - 1]);
    }
    new_comb = clean_set(new_comb);
    for (auto &&query : queries[pos]) {
      const li i = query.first;
      const li l = query.second;
      ans[i] = solve(new_comb, second_half, l);
    }
    for (int next = 0; next < 2; ++next) {
      li next_pos = pos * 2 + next;
      if (next_pos <= n) {
        dfs(next_pos, new_comb, second_half);
      }
    }
  } else {
    vector<pair<li, li>> new_comb;
    new_comb = second_half;
    for (auto &&p : second_half) {
      new_comb.emplace_back(p.first + wes[pos - 1], p.second + vs[pos - 1]);
    }
    for (auto &&query : queries[pos]) {
      const li i = query.first;
      const li l = query.second;
      ans[i] = solve(first_half, new_comb, l);
    }
    for (int next = 0; next < 2; ++next) {
      li next_pos = pos * 2 + next;
      if (next_pos <= n) {
        dfs(next_pos, first_half, new_comb);
      }
    }
  }
}

int main() {
  //    cin.tie(0);
  //    ios::sync_with_stdio(false);

  scanf("%d", &n);
  vs = vector<li>(n);
  wes = vector<li>(n);
  for (int i = 0; i < n; ++i) {
    scanf("%d %d", &vs[i], &wes[i]);
  }

  li q;
  scanf("%d", &q);
  ans = vector<li>(q);
  for (int i = 0; i < q; ++i) {
    li v, l;
    scanf("%d %d", &v, &l);

    queries[v].emplace_back(i, l);
    while (v > 0) {
      need_to_visit.insert(v);
      v /= 2;
    }
  }

  //    n = 1LL << 18;
  //    vs = vector<li>(n);
  //    wes = vector<li>(n);
  //    for (int i = 0; i < n; ++i) {
  //        vs[i] = wes[i] = i + 1;
  //    }
  //
  //    li q;
  //    q = 1e5;
  //    ans = vector<li>(q);
  //    for (int i = 0; i < q; ++i) {
  //        li v, l;
  //        v = n - 1 - i;
  //        l = i;
  //        queries[v].emplace_back(i, l);
  //        while (v > 0) {
  //            need_to_visit.insert(v);
  //            v /= 2;
  //        }
  //    }

  set<pair<li, li>> empty_comb = {make_pair(0, 0)};
  vector<pair<li, li>> vec_empty_comb = {make_pair(0, 0)};
  dfs(1, empty_comb, vec_empty_comb);

  for (int i = 0; i < q; ++i) {
    printf("%d\\n", ans[i]);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
typedef int li;

li n;
vector<li> vs, wes;

vector<li> ans;
map<li, vector<pair<li, li>>> queries;
set<li> need_to_visit;

set<pair<li, li>> clean_set(const set<pair<li, li>> &orig) {
  set<pair<li, li>> ret;
  li maxv = -1;
  for (auto &&item : orig) {
    if (item.second > maxv) {
      maxv = item.second;
      ret.insert(item);
    }
  }
  return ret;
}

li solve(const set<pair<li, li>> &first_half,
         const set<pair<li, li>> &second_half, const li l) {
  li maxv = 0;
  for (auto &&item : second_half) {
    const li rem = l - item.first;
    if (rem >= 0) {
      auto ptr = first_half.lower_bound(make_pair(rem + 1, -1));
      ptr--;
      maxv = max(maxv, item.second + ptr->second);
    }
  }
  return maxv;
}

void dfs(const li pos, const set<pair<li, li>> &first_half,
         const set<pair<li, li>> &second_half) {
  if (need_to_visit.find(pos) == need_to_visit.end()) {
    return;
  }

  const bool is_first = pos < 4096;

  set<pair<li, li>> new_comb;
  if (is_first) {
    new_comb = first_half;
    for (auto &&p : first_half) {
      new_comb.emplace(p.first + wes[pos - 1], p.second + vs[pos - 1]);
    }
    new_comb = clean_set(new_comb);
  } else {
    new_comb = second_half;
    for (auto &&p : second_half) {
      new_comb.emplace(p.first + wes[pos - 1], p.second + vs[pos - 1]);
    }
    new_comb = clean_set(new_comb);
  }
  for (auto &&query : queries[pos]) {
    const li i = query.first;
    const li l = query.second;
    if (is_first) {
      ans[i] = solve(new_comb, second_half, l);
    } else {
      ans[i] = solve(first_half, new_comb, l);
    }
  }

  for (int next = 0; next < 2; ++next) {
    li next_pos = pos * 2 + next;
    if (next_pos <= n) {
      if (is_first) {
        dfs(next_pos, new_comb, second_half);
      } else {
        dfs(next_pos, first_half, new_comb);
      }
    }
  }
}

int main() {
  //    cin.tie(0);
  //    ios::sync_with_stdio(false);

  scanf("%d", &n);
  vs = vector<li>(n);
  wes = vector<li>(n);
  for (int i = 0; i < n; ++i) {
    scanf("%d %d", &vs[i], &wes[i]);
  }

  li q;
  scanf("%d", &q);
  ans = vector<li>(q);
  for (int i = 0; i < q; ++i) {
    li v, l;
    scanf("%d %d", &v, &l);

    queries[v].emplace_back(i, l);
    while (v > 0) {
      need_to_visit.insert(v);
      v /= 2;
    }
  }

  //    n = 1LL << 18;
  //    vs = vector<li>(n);
  //    wes = vector<li>(n);
  //    for (int i = 0; i < n; ++i) {
  //        vs[i] = wes[i] = i + 1;
  //    }
  //
  //    li q;
  //    q = 1e5;
  //    ans = vector<li>(q);
  //    for (int i = 0; i < q; ++i) {
  //        li v, l;
  //        v = n - 1 - i;
  //        l = i;
  //        queries[v].emplace_back(i, l);
  //        while (v > 0) {
  //            need_to_visit.insert(v);
  //            v /= 2;
  //        }
  //    }

  set<pair<li, li>> empty_comb = {make_pair(0, 0)};
  dfs(1, empty_comb, empty_comb);

  for (int i = 0; i < q; ++i) {
    printf("%d\\n", ans[i]);
  }

  return 0;
}