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

#include <bits/stdc++.h>
#define PB push_back
#define FI first
#define SE second
#define MP make_pair
#define int long long
using namespace std;
static const int inf = 1ll << 60;
static const int MAX_N = 16777216;
typedef pair<int, int> P;

int N, D;
int X[40], Y[40];
int ans = 0;
int dat[MAX_N * 2];
vector<P> p1;
vector<P> p2;

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 half(int n, int last, int x, int y, vector<P> &res) {
  if (n == last) {
    res.PB(P(x, y));
    return;
  }
  half(n - 1, last, x + X[n], y + Y[n], res);
  half(n - 1, last, x - X[n], y - Y[n], res);
  half(n - 1, last, x, y, res);
}

signed main() {
  cin >> N >> D;
  Segment seg;
  int n2 = N / 2;
  for (int i = 1; i <= N; ++i) {
    cin >> X[i] >> Y[i];
  }
  p1.reserve(MAX_N);
  half(n2, 0, 0, 0, p1);
  p2.reserve(MAX_N);
  half(N, n2, 0, 0, p2);
  sort(p2.begin(), p2.end());
  seg.inti(p2.size());
  for (int i = 0; i < p2.size(); ++i)
    seg.update(i, p2[i].SE);
  for (int i = 0; i < p1.size(); ++i) {
    int x = p1[i].FI + D;
    int y = p1[i].FI - D;
    int r = lower_bound(p2.begin(), p2.end(), MP(y, -inf)) - p2.begin();
    int l = upper_bound(p2.begin(), p2.end(), MP(x, inf)) - p2.begin();
    if (r == p2.size())
      continue;
    if (r >= l)
      continue;
    ans = max(ans, seg.query(r, l, 0, 0, seg.n) - p1[i].SE);
  }
  cout << ans << endl;
}

Error: TLE

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) {
  // cout<<v<<" "<<w<<endl;
  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;
  int N2 = N - N1;
  An.reserve(MAX_N);
  Bu.reserve(MAX_N);
  dfs(0, N1, 0, 0, An);
  dfs(N1, N, 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;
}