Problem p02347 (C++) — buggy submission, verdict: Time 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 MAX_N = 500010;

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;

  void *operator new(std::size_t) {
    static node pool[MAX_N];
    static int p = 0;
    return pool + p++;
  }
};

using np = node *;
using cnp = const node *;
using dp = dat_t *;
using cdp = const dat_t *;

np make_tree(cdp *left, cdp *right, int d) {
  d %= D;

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

  sort(left, right, [d](cdp a, cdp b) { return (*a)[d] < (*b)[d]; });

  np res = new node;
  for (int d = 0; d < D; ++d) {
    res->min[d] = (**left)[d];
    res->max[d] = (**left)[d];
    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]);
    }
  }
  res->key = left[sz / 2];
  res->left = sz > 1 ? make_tree(left, left + sz / 2, d + 1) : nullptr;
  res->right = sz > 1 ? make_tree(left + sz / 2 + 1, right, d + 1) : nullptr;
  res->size = sz;

  return res;
}

cnp make_tree(cdp left, cdp right) {
  static cdp ptr[MAX_N];
  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(cnp n, const dat_t &min, const dat_t &max,
                 std::vector<std::pair<cdp, cnp>> &ans) {
  if (n == nullptr)
    return;

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

using namespace std;
dat_t ps[MAX_N];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin >> n;
  for (int i = 0; i < n; ++i)
    cin >> ps[i][0] >> ps[i][1];
  cnp 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);
        }
      }
    }
    sort(ans.begin(), ans.end());
    for (auto &p : ans) {
      cout << p - ps << '\\n';
    }
    cout << '\\n';
  }
}

Error: TLE

Fixed submission:

#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 MAX_N = 500010;

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;

  void *operator new(std::size_t) {
    static node pool[MAX_N];
    static int p = 0;
    return pool + p++;
  }
};

using np = node *;
using cnp = const node *;
using dp = dat_t *;
using cdp = const dat_t *;

np make_tree(cdp *left, cdp *right, int d) {
  d %= D;

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

  sort(left, right, [d](cdp a, cdp b) { return (*a)[d] < (*b)[d]; });

  np res = new node;
  for (int d = 0; d < D; ++d) {
    res->min[d] = (**left)[d];
    res->max[d] = (**left)[d];
    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]);
    }
  }
  res->key = left[sz / 2];
  res->left = sz > 1 ? make_tree(left, left + sz / 2, d + 1) : nullptr;
  res->right = sz > 1 ? make_tree(left + sz / 2 + 1, right, d + 1) : nullptr;
  res->size = sz;

  return res;
}

cnp make_tree(cdp left, cdp right) {
  static cdp ptr[MAX_N];
  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(cnp n, const dat_t &min, const dat_t &max,
                 std::vector<std::pair<cdp, cnp>> &ans) {
  if (n == nullptr)
    return;

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

using namespace std;
dat_t ps[MAX_N];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin >> n;
  for (int i = 0; i < n; ++i)
    cin >> ps[i][0] >> ps[i][1];
  cnp 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);
        }
      }
    }
    sort(ans.begin(), ans.end());
    for (auto &p : ans) {
      cout << p - ps << '\\n';
    }
    cout << '\\n';
  }
}