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

#include <bits/stdc++.h>
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(c) begin(c), end(c)
#define dump(x) std::cerr << __LINE__ << ":\\t" #x " = " << (x) << std::endl

const int D = 2;
using value_t = int;
using dat_t = std::array<value_t, D>;

struct node {
  const dat_t *key;
  dat_t min, max;
  int size;

  node *left, *right;
};

node *make_tree(const dat_t **left, const dat_t **right, int d) {
  d %= D;

  int sz = right - left;
  if (sz <= 0)
    return nullptr;

  node *res = new node;
  for (int d = 0; d < D; ++d) {
    res->min[d] = std::numeric_limits<int>::max();
    res->max[d] = std::numeric_limits<int>::min();
    for (auto i = left; i != right; ++i) {
      res->min[d] = std::min(res->min[d], (**i)[d]);
      res->max[d] = std::max(res->max[d], (**i)[d]);
    }
  }

  sort(left, right,
       [d](const dat_t *a, const dat_t *b) { return (*a)[d] < (*b)[d]; });
  res->key = left[sz / 2];

  if (sz > 1) {
    res->left = make_tree(left, left + sz / 2, d + 1);
    res->right = make_tree(left + sz / 2 + 1, right, d + 1);
  } else {
    res->left = nullptr;
    res->right = nullptr;
  }
  res->size = sz;
  return res;
}

node *make_tree(const dat_t *left, const dat_t *right) {
  static const dat_t *ptr[500010];
  int sz = right - left;
  for (auto i = left; i != right; ++i)
    ptr[i - left] = i;
  return make_tree(ptr, ptr + sz, 0);
}

void range_query(const node *n, const dat_t &min, const dat_t &max,
                 std::vector<std::pair<const dat_t *, const node *>> &ans) {
  if (n == nullptr)
    return;

  int overwrap = 2;
  // for(int d = 0; d < D; ++d){
  //     dump(n->min[d]);
  //     dump(n->max[d]);
  // }

  // dump(min[0]);
  // dump(max[0]);
  // dump(min[1]);
  // dump(max[1]);

  for (int d = 0; d < D; ++d) {
    if (n->max[d] < min[d] || max[d] < n->min[d]) {
      overwrap = 0;
      break;
    } else if (!(min[d] <= n->min[d] && n->max[d] <= max[d])) {
      overwrap = 1;
    }
  }

  // dump(overwrap);

  if (overwrap == 0) {
    ;
  } else if (overwrap == 1) {
    bool inner = true;
    for (int d = 0; d < D; ++d) {
      if (!(min[d] <= (*n->key)[d] && (*n->key)[d] <= max[d])) {
        inner = false;
        break;
      }
    }
    if (inner)
      ans.emplace_back(n->key, nullptr);
    range_query(n->left, min, max, ans);
    range_query(n->right, min, max, ans);
  } else {
    ans.emplace_back(nullptr, n);
  }
}

using namespace std;
dat_t ps[500010];

int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> ps[i][0] >> ps[i][1];
  }
  node *root = make_tree(ps, ps + n);

  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    dat_t min, max;
    cin >> min[0] >> max[0] >> min[1] >> max[1];
    vector<pair<const dat_t *, const node *>> res;
    range_query(root, min, max, res);
    vector<const dat_t *> ans;
    for (auto &p : res) {
      if (p.first != nullptr) {
        ans.push_back(p.first);
      } else if (p.second != nullptr) {
        stack<const node *> stk;
        stk.push(p.second);
        while (stk.size()) {
          auto c = stk.top();
          stk.pop();
          if (c == nullptr)
            continue;
          ans.push_back(c->key);
          stk.push(c->left);
          stk.push(c->right);
        }
      } else {
        assert(false);
      }
    }
    sort(ans.begin(), ans.end());
    for (auto &p : ans) {
      cout << p - ps << '\\n';
    }
    cout << '\\n';
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(c) begin(c), end(c)
#define dump(x) cerr << __LINE__ << ":\\t" #x " = " << (x) << endl

const int INF = 1e9 + 10;
using dat_t = tuple<int, int>;

const int MAX_N = 500010;

vector<const dat_t *> seg[MAX_N * 2];
int x_min[MAX_N * 2], x_max[MAX_N * 2];
int size[MAX_N * 2];

bool comp_x(const dat_t *a, const dat_t *b) { return get<0>(*a) < get<0>(*b); }

bool comp_y(const dat_t *a, const dat_t *b) { return get<1>(*a) < get<1>(*b); }

void make_tree(const dat_t **left, const dat_t **right, int n) {
  int sz = right - left;
  x_min[n] = get<0>(**left);
  x_max[n] = get<0>(**(right - 1));
  auto &par = seg[n];
  std::copy(left, right, std::back_inserter(par));
  sort(par.begin(), par.end(), comp_y);
  if (sz > 1) {
    make_tree(left, left + sz / 2, n * 2);
    make_tree(left + sz / 2, right, n * 2 + 1);
  }
}

void make_tree(const dat_t *left, const dat_t *right) {
  static const dat_t *ptr[500010];
  int sz = right - left;
  for (auto i = left; i != right; ++i)
    ptr[i - left] = i;
  sort(ptr, ptr + sz, comp_x);
  make_tree(ptr, ptr + sz, 1);
}

void y_query(int y1, int y2, vector<const dat_t *> &ans, int n) {
  auto t = make_tuple(-INF, y1);
  auto u = make_tuple(-INF, y2);
  auto l = lower_bound(seg[n].begin(), seg[n].end(), &t, comp_y);
  auto r = upper_bound(seg[n].begin(), seg[n].end(), &u, comp_y);
  std::copy(l, r, std::back_inserter(ans));
}

void range_query(int x1, int x2, int y1, int y2, vector<const dat_t *> &ans,
                 int n) {
  if (x_max[n] < x1 || x2 < x_min[n]) {
    ;
  } else if (x1 <= x_min[n] && x_max[n] <= x2) {
    y_query(y1, y2, ans, n);
  } else {
    range_query(x1, x2, y1, y2, ans, n * 2);
    range_query(x1, x2, y1, y2, ans, n * 2 + 1);
  }
}

void range_query(int x1, int x2, int y1, int y2, vector<const dat_t *> &ans) {
  range_query(x1, x2, y1, y2, ans, 1);
}

dat_t ps[500010];

int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    ps[i] = make_tuple(x, y);
  }
  make_tree(ps, ps + n);

  // for(int i = 0; i < MAX_N*2; ++i){
  //     cout << "##### " << i << endl;
  //     cout << "r " << x_min[i] << ' ' << x_min[i] << endl;
  //     for(auto &p : seg[i]){
  //         cout << get<0>(*p) << ' ' << get<1>(*p) << endl;
  //     }
  // }

  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    int sx, tx, sy, ty;
    cin >> sx >> tx >> sy >> ty;
    vector<const dat_t *> ans;
    range_query(sx, tx, sy, ty, ans);
    sort(ans.begin(), ans.end());
    for (auto &p : ans) {
      cout << p - ps << '\\n';
    }
    cout << '\\n';
  }
}