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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; ++i)
#define rep(i, n) REP(i, 0, n)
#define ALL(x) x.begin(), x.end()

using namespace std;

typedef long long ll;

#define MAX 31
#define IINF LLONG_MAX

class RMQ {
private:
  int limit, N;
  vector<ll> dat;

public:
  void init(int n_) {
    N = n_;
    limit = 1LL;
    while (limit < n_)
      limit *= 2;
    dat.clear();
    dat.resize(2 * limit, -IINF);
  }

  ll _build(int cur, int L, int R, const vector<ll> &buf) {
    if (!(0 <= cur && cur < 2 * limit))
      return -IINF;
    if (L == R - 1) {
      if (L >= N)
        return -IINF;
      dat[cur] = buf[L];
    } else {
      ll vl = _build(cur * 2 + 1, L, (L + R) / 2, buf);
      ll vr = _build(cur * 2 + 2, (L + R) / 2, R, buf);
      dat[cur] = max(vl, vr);
    }
    return dat[cur];
  }

  void build(const vector<ll> &buf) { _build(0, 0, limit, buf); };

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

  ll query(int a, int b) { return _query(a, b, 0, 0, limit); }
};

int N;
ll D, X[MAX], Y[MAX];
struct Data {
  ll v, w;
  bool operator==(const Data &data) const { return v == data.v && w == data.w; }
  bool operator<(const Data &data) const {
    if (v != data.v)
      return v < data.v;
    return w > data.w;
  }
};
vector<Data> v1, v2;

void dfs(vector<Data> &vec, int base, int cur, int rem, ll v, ll w) {
  if (rem <= 0) {
    // mp[v] = max(mp[v],w);
    vec.push_back((Data){v, w});
    return;
  }
  int ID = base + cur;
  assert(ID < N);
  dfs(vec, base, cur + 1, rem - 1, v, w);
  dfs(vec, base, cur + 1, rem - 1, v - X[ID], w - Y[ID]); // Anna
  dfs(vec, base, cur + 1, rem - 1, v + X[ID], w + Y[ID]); // Bruno
}

void compute() {
  {
    int M = N / 2;
    dfs(v1, 0, 0, M, 0, 0);
    // puts("-");
    sort(ALL(v1));
    // puts("--");
    v1.erase(unique(ALL(v1)), v1.end());
    // puts("---");
    vector<Data> tvec;
    ll cur = -IINF;
    rep(i, (int)v1.size()) if (v1[i].v != cur) {
      cur = v1[i].v;
      tvec.push_back(v1[i]);
    }
    v1 = tvec;
    tvec.clear();
    cur = -IINF;
    // puts("-----");
    dfs(v2, M, 0, N - M, 0, 0);
    // puts("------");
    sort(ALL(v2));
    // puts("-------");
    v2.erase(unique(ALL(v2)), v2.end());
    // puts("--------");
    rep(i, (int)v2.size()) if (v2[i].v != cur) {
      cur = v2[i].v;
      tvec.push_back(v2[i]);
    }
    v2 = tvec;
    // puts("---------");
  }
  RMQ rmq;
  vector<ll> vec;
  {
    vector<ll> buf;
    for (auto v : v2) {
      vec.push_back(v.v);
      buf.push_back(v.w);
    }
    rmq.init((int)buf.size());
    rmq.build(buf);
  }

  ll ans = 0;
  for (auto v : v1) {
    int ptr_L = lower_bound(vec.begin(), vec.end(), -D - v.v) - vec.begin();
    int ptr_R = upper_bound(vec.begin(), vec.end(), D - v.v) - vec.begin();
    if (llabs(v.v + vec[ptr_L]) > D)
      continue;
    ans = max(ans, v.w + rmq.query(ptr_L, ptr_R));
  }
  cout << ans << endl;
}

int main() {
  if (0) {
    N = 30;
    D = 1000000000000000LL;
    cout << N << " " << D << endl;
    rep(i, N) { cout << rand() << " " << rand() << endl; }
    return 0;
  }
  cin >> N >> D;
  rep(i, N) cin >> X[i] >> Y[i];
  compute();
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; ++i)
#define rep(i, n) REP(i, 0, n)
#define ALL(x) x.begin(), x.end()

using namespace std;

typedef long long ll;

#define MAX 31
#define IINF LLONG_MAX

class RMQ {
private:
  int limit, N;
  vector<ll> dat;

public:
  void init(int n_) {
    N = n_;
    limit = 1LL;
    while (limit < n_)
      limit *= 2;
    dat.clear();
    dat.resize(2 * limit, -IINF);
  }

  ll _build(int cur, int L, int R, const vector<ll> &buf) {
    if (!(0 <= cur && cur < 2 * limit))
      return -IINF;
    if (L == R - 1) {
      if (L >= N)
        return -IINF;
      dat[cur] = buf[L];
    } else {
      ll vl = _build(cur * 2 + 1, L, (L + R) / 2, buf);
      ll vr = _build(cur * 2 + 2, (L + R) / 2, R, buf);
      dat[cur] = max(vl, vr);
    }
    return dat[cur];
  }

  void build(const vector<ll> &buf) { _build(0, 0, limit, buf); };

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

  ll query(int a, int b) { return _query(a, b, 0, 0, limit); }
};

int N;
ll D, X[MAX], Y[MAX];
struct Data {
  ll v, w;
  bool operator==(const Data &data) const { return v == data.v && w == data.w; }
  bool operator<(const Data &data) const {
    if (v != data.v)
      return v < data.v;
    return w > data.w;
  }
};
vector<Data> v1, v2;

void dfs(vector<Data> &vec, int base, int cur, int rem, ll v, ll w) {
  if (rem <= 0) {
    // mp[v] = max(mp[v],w);
    vec.push_back((Data){v, w});
    return;
  }
  int ID = base + cur;
  assert(ID < N);
  dfs(vec, base, cur + 1, rem - 1, v, w);
  dfs(vec, base, cur + 1, rem - 1, v - X[ID], w - Y[ID]); // Anna
  dfs(vec, base, cur + 1, rem - 1, v + X[ID], w + Y[ID]); // Bruno
}

void compute() {
  int M = N / 2;
  dfs(v1, 0, 0, M, 0, 0);
  // puts("-");
  sort(ALL(v1));
  // puts("--");
  v1.erase(unique(ALL(v1)), v1.end());
  // puts("---");
  vector<Data> tvec;
  ll cur = -IINF;
  rep(i, (int)v1.size()) if (v1[i].v != cur) {
    cur = v1[i].v;
    tvec.push_back(v1[i]);
  }
  v1 = tvec;
  tvec.clear();
  cur = -IINF;
  // puts("-----");
  dfs(v2, M, 0, N - M, 0, 0);
  // puts("------");
  sort(ALL(v2));
  // puts("-------");
  v2.erase(unique(ALL(v2)), v2.end());
  // puts("--------");
  rep(i, (int)v2.size()) if (v2[i].v != cur) {
    cur = v2[i].v;
    tvec.push_back(v2[i]);
  }
  v2 = tvec;
  // puts("---------");

  RMQ rmq;
  vector<ll> vec;
  {
    vector<ll> buf;
    for (auto v : v2) {
      vec.push_back(v.v);
      buf.push_back(v.w);
    }
    rmq.init((int)buf.size());
    rmq.build(buf);
  }

  ll ans = 0;
  for (auto v : v1) {
    int ptr_L = lower_bound(vec.begin(), vec.end(), -D - v.v) - vec.begin();
    int ptr_R = upper_bound(vec.begin(), vec.end(), D - v.v) - vec.begin();
    if (llabs(v.v + vec[ptr_L]) > D)
      continue;
    ans = max(ans, v.w + rmq.query(ptr_L, ptr_R));
  }
  cout << ans << endl;
}

int main() {
  if (0) {
    N = 30;
    D = 1000000000000000LL;
    cout << N << " " << D << endl;
    rep(i, N) { cout << rand() << " " << rand() << endl; }
    return 0;
  }
  cin >> N >> D;
  rep(i, N) cin >> X[i] >> Y[i];
  compute();
  return 0;
}