Problem p00536 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define MP make_pair
#define PB push_back
#define FI first
#define SE second
typedef tuple<int, int> T1;
static const int INF = 1ll << 60;
static const int dx[] = {
    1,
    -1,
    0,
    0,
};
static const int dy[] = {0, 0, 1, -1};

int N, D;
int V[35], W[35];
int dat[16777216];
int ans = 0;
vector<T1> P1, P2;

class Segment {
public:
  int n;
  void init(int _n) {
    n = 1;
    while (n < _n)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; ++i)
      dat[i] = -INF;
  }
  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 (r <= a || b <= l)
      return -INF;
    if (a <= l && r <= b)
      return dat[k];
    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 half(int n, int End, int v, int w, vector<T1> &S) {
  if (n == End) {
    S.push_back(make_tuple(v, w));
    return;
  }
  half(n + 1, End, v + V[n], w + W[n], S);
  half(n + 1, End, v - V[n], w - W[n], S);
  half(n + 1, End, v, w, S);
}

signed main() {
  cin >> N >> D;
  for (int i = 0; i < N; ++i)
    cin >> V[i] >> W[i];
  half(0, N / 2, 0, 0, P1);
  half(N / 2, N, 0, 0, P2);
  sort(P1.begin(), P1.end());
  sort(P2.begin(), P2.end());
  Segment seg;
  seg.init(P2.size());
  for (int i = 0; i < P2.size(); ++i)
    seg.update(i, get<1>(P2[i]));
  for (int i = 0; i < P1.size(); ++i) {
    int x, y;
    int a, b;
    tie(x, y) = P1[i];
    a = min(D - x, -D - x);
    b = max(D - x, -D - x);
    int lit =
        lower_bound(P2.begin(), P2.end(), make_tuple(a, -INF)) - P2.begin();
    int rit =
        upper_bound(P2.begin(), P2.end(), make_tuple(b, INF)) - P2.begin();
    if (rit == P2.size() || lit == rit)
      continue;
    if (lit > rit)
      continue;
    ans = max(ans, abs(y + seg.query(lit, rit, 0, 0, seg.n)));
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define MP make_pair
#define PB push_back
#define FI first
#define SE second
typedef tuple<int, int> T1;
static const int INF = 1ll << 60;
static const int dx[] = {
    1,
    -1,
    0,
    0,
};
static const int dy[] = {0, 0, 1, -1};

int N, D;
int V[35], W[35];
int dat[16777216 * 2 - 1];
int ans = 0;
vector<T1> P1, P2;

class Segment {
public:
  int n;
  void init(int _n) {
    n = 1;
    while (n < _n)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; ++i)
      dat[i] = -INF;
  }
  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 (r <= a || b <= l)
      return -INF;
    if (a <= l && r <= b)
      return dat[k];
    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 half(int n, int End, int v, int w, vector<T1> &S) {
  if (n == End) {
    S.push_back(make_tuple(v, w));
    return;
  }
  half(n + 1, End, v + V[n], w + W[n], S);
  half(n + 1, End, v - V[n], w - W[n], S);
  half(n + 1, End, v, w, S);
}

signed main() {
  cin >> N >> D;
  for (int i = 0; i < N; ++i)
    cin >> V[i] >> W[i];
  half(0, N / 2, 0, 0, P1);
  half(N / 2, N, 0, 0, P2);
  sort(P1.begin(), P1.end());
  sort(P2.begin(), P2.end());
  Segment seg;
  seg.init(P2.size());
  for (int i = 0; i < P2.size(); ++i)
    seg.update(i, get<1>(P2[i]));
  for (int i = 0; i < P1.size(); ++i) {
    int x, y;
    int a, b;
    tie(x, y) = P1[i];
    a = min(D - x, -D - x);
    b = max(D - x, -D - x);
    int lit =
        lower_bound(P2.begin(), P2.end(), make_tuple(a, -INF)) - P2.begin();
    int rit =
        upper_bound(P2.begin(), P2.end(), make_tuple(b, INF)) - P2.begin();
    if (rit == P2.size() || lit == rit)
      continue;
    if (lit > rit)
      continue;
    ans = max(ans, abs(y + seg.query(lit, rit, 0, 0, seg.n)));
  }
  cout << ans << endl;
}