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


#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

using namespace std;

constexpr static int MAXN = 3e5 + 10;
constexpr static int MAXL = 1e5 + 10;
constexpr static int N1 = (1 << 9);

int n;
int v[MAXN], w[MAXN];
vector<pair<int, int>> dp[N1];

void dp_step(const vector<pair<int, int>> &cur, vector<pair<int, int>> &nxt,
             int u, int L) {
  const auto &a = cur;
  vector<pair<int, int>> b;
  for (auto p : cur)
    if (p.first + w[u] <= L)
      b.push_back({p.first + w[u], p.second + v[u]});

  int i = 0, j = 0;
  while (i < a.size() && j < b.size()) {
    if (a[i].first < b[j].first) {
      if (nxt.size() == 0 || a[i].second > nxt.back().second)
        nxt.push_back(a[i]);
      i++;
    } else if (a[i].first > b[j].first) {
      if (nxt.size() == 0 || b[j].second > nxt.back().second)
        nxt.push_back(b[j]);
      j++;
    } else {
      int vmax = max(a[i].second, b[j].second);
      if (nxt.size() == 0 || vmax > nxt.back().second)
        nxt.push_back({a[i].first, vmax});
      i++, j++;
    }
  }
  while (i < a.size()) {
    if (nxt.size() == 0 || a[i].second > nxt.back().second)
      nxt.push_back(a[i]);
    i++;
  }
  while (j < b.size()) {
    if (nxt.size() == 0 || b[j].second > nxt.back().second)
      nxt.push_back(b[j]);
    j++;
  }
}

void init() {
  dp[0].push_back({0, 0});
  for (int i = 1; i <= n && i < N1; i++)
    dp_step(dp[i >> 1], dp[i], i, MAXL);
}

int query(int u, int L) {
  vector<pair<int, int>> cur, nxt;
  cur.push_back({0, 0});
  while (u >= N1) {
    if (w[u] <= L) {
      dp_step(cur, nxt, u, L);
      cur = nxt;
      nxt.clear();
    }
    u /= 2;
  }

  const auto &a = dp[u];
  const auto &b = cur;
  int j = b.size() - 1;
  int vmax = 0;
  for (int i = 0; i < a.size(); i++) {
    while (j > 0 && a[i].first + b[j].first > L)
      j--;
    if (a[i].first + b[j].first <= L)
      vmax = max(vmax, a[i].second + b[j].second);
  }

  return vmax;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> v[i] >> w[i];

  init();

  int q;
  cin >> q;
  while (q--) {
    int u, L;
    cin >> u >> L;
    cout << query(u, L) << '\\n';
  }
}


Error: TLE

Fixed submission:


#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

using namespace std;

constexpr static int MAXN = 3e5 + 10;
constexpr static int MAXL = 1e5 + 10;
constexpr static int N1 = (1 << 9);

int n;
int v[MAXN], w[MAXN];
vector<pair<int, int>> dp[N1];

void dp_step(const vector<pair<int, int>> &cur, vector<pair<int, int>> &nxt,
             int i, int L) {
  vector<pair<int, int>> a = cur;
  for (auto p : cur)
    if (p.first + w[i] <= L)
      a.push_back({p.first + w[i], p.second + v[i]});
  // make this a merge instead?
  sort(a.begin(), a.end());
  for (auto p : a) {
    if (nxt.size() > 0) {
      if (nxt.back().first == p.first) {
        nxt.back().second = p.second;
        continue;
      }
      if (p.second <= nxt.back().second)
        continue;
    }
    nxt.push_back(p);
  }
}

void init() {
  dp[0].push_back({0, 0});
  for (int i = 1; i <= n && i < N1; i++)
    dp_step(dp[i >> 1], dp[i], i, MAXL);
}

int query(int u, int L) {
  vector<pair<int, int>> cur, nxt;
  cur.push_back({0, 0});
  while (u >= N1) {
    if (w[u] <= L) {
      dp_step(cur, nxt, u, L);
      cur = nxt;
      nxt.clear();
    }
    u /= 2;
  }

  const auto &a = dp[u];
  const auto &b = cur;
  int j = b.size() - 1;
  int vmax = 0;
  for (int i = 0; i < a.size(); i++) {
    while (j > 0 && a[i].first + b[j].first > L)
      j--;
    if (a[i].first + b[j].first <= L)
      vmax = max(vmax, a[i].second + b[j].second);
  }

  return vmax;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> v[i] >> w[i];

  init();

  int q;
  cin >> q;
  while (q--) {
    int u, L;
    cin >> u >> L;
    cout << query(u, L) << '\\n';
  }
}