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

#include <bits/stdc++.h>
#define int long long
#define PB push_back
#define FI first
#define SE second
using namespace std;
typedef pair<int, int> pii;
static const int inf = 1ll << 60;
static const int MAX_N = 16777216;
int N, D;
int W[35];
int V[35];
int dat[MAX_N * 2];
vector<pii> An, Bu;

class Segment {
public:
  int n;
  void inti(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; ++i)
      dat[i] = -INT_MAX;
  }

  void update(int k, int a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  int query(int a, int b, int k, int l, int r) {
    if (a <= l && r <= b)
      return dat[k];
    if (r <= a || b <= l)
      return -INT_MAX;
    else {
      int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return max(vl, vr);
    }
  }
};

void dfs(int n, int l, int w, int v, vector<pii> &res) {
  if (n == l) {
    res.PB(pii(w, v));
    return;
  }
  dfs(n - 1, l, w + W[n], v + V[n], res);
  dfs(n - 1, l, w - W[n], v - V[n], res);
  dfs(n - 1, l, w, v, res);
}

signed main() {
  cin >> N >> D;
  for (int i = 1; i <= N; ++i)
    cin >> W[i] >> V[i];
  Segment seg;
  int N1 = N / 2;
  An.reserve(MAX_N);
  dfs(N1, 0, 0, 0, An);
  Bu.reserve(MAX_N);
  dfs(N, N1, 0, 0, Bu);
  seg.inti(Bu.size());
  sort(Bu.begin(), Bu.end());
  for (int i = 0; i < Bu.size(); ++i)
    seg.update(i, Bu[i].SE);
  int ans = 0;
  for (int i = 0; i < An.size(); ++i) {
    int x = An[i].FI + D;
    int y = An[i].FI - D;
    int r = upper_bound(Bu.begin(), Bu.end(), make_pair(x, inf)) - Bu.begin();
    int l = lower_bound(Bu.begin(), Bu.end(), make_pair(y, -inf)) - Bu.begin();
    if (l == Bu.size())
      continue;
    if (l >= r)
      continue;
    ans = max(ans, seg.query(l, r, 0, 0, seg.n) - An[i].SE);
  }
  cout << ans << endl;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define int long long
#define PB push_back
#define FI first
#define SE second
using namespace std;
typedef pair<int, int> pii;
static const int inf = 1ll << 60;
static const int MAX_N = 16777216;
int N, D;
int W[35];
int V[35];
int dat[MAX_N * 2];
vector<pii> An, Bu;

class Segment {
public:
  int n;
  void inti(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; ++i)
      dat[i] = -INT_MAX;
  }

  void update(int k, int a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  int query(int a, int b, int k, int l, int r) {
    if (a <= l && r <= b)
      return dat[k];
    if (r <= a || b <= l)
      return -INT_MAX;
    else {
      int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return max(vl, vr);
    }
  }
};

void dfs(int n, int l, int w, int v, vector<pii> &res) {
  if (n == l) {
    res.PB(pii(w, v));
    return;
  }
  dfs(n - 1, l, w + W[n], v + V[n], res);
  dfs(n - 1, l, w - W[n], v - V[n], res);
  dfs(n - 1, l, w, v, res);
}

signed main() {
  cin >> N >> D;
  for (int i = 0; i < N; ++i)
    cin >> W[i] >> V[i];
  Segment seg;
  int N1 = N / 2;
  An.reserve(MAX_N);
  dfs(N1, -1, 0, 0, An);
  Bu.reserve(MAX_N);
  dfs(N, N1, 0, 0, Bu);
  seg.inti(Bu.size());
  sort(Bu.begin(), Bu.end());
  for (int i = 0; i < Bu.size(); ++i)
    seg.update(i, Bu[i].SE);
  int ans = 0;
  for (int i = 0; i < An.size(); ++i) {
    int x = An[i].FI + D;
    int y = An[i].FI - D;
    int r = upper_bound(Bu.begin(), Bu.end(), make_pair(x, inf)) - Bu.begin();
    int l = lower_bound(Bu.begin(), Bu.end(), make_pair(y, -inf)) - Bu.begin();
    if (l == Bu.size())
      continue;
    if (l >= r)
      continue;
    ans = max(ans, seg.query(l, r, 0, 0, seg.n) - An[i].SE);
  }
  cout << ans << endl;
}