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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
template <class T> inline void read(T &x) {
  char c = getchar();
  T p = 1, n = 0;
  while (c < '0' || c > '9') {
    if (c == '-')
      p = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    n = n * 10 + c - '0';
    c = getchar();
  }
  x = p * n;
}
template <class T, class U> inline void read(T &x, U &y) { read(x), read(y); }
template <class T, class U, class V> inline void read(T &x, U &y, V &z) {
  read(x), read(y), read(z);
}
const int maxn = 5e5 + 100;
int D;
int n, root;
struct Point {
  int d[2], l, r, num;
  Point() { l = 0, r = 0; }
  int &operator[](int i) { return d[i]; }
  bool operator<(const Point &p) const { return d[D] < p.d[D]; }
} P[maxn], t[maxn];
int tc = 1;
int build(int L = 0, int R = n - 1, int d = 0) {
  int M = (L + R) >> 1;
  D = d;
  nth_element(P + L, P + M, P + R + 1);
  int o = tc++;
  t[o] = P[M];
  if (L < M)
    t[o].l = build(L, M - 1, d ^ 1);
  if (M < R)
    t[o].r = build(M + 1, R, d ^ 1);
  return o;
}
int sx, tx, sy, ty;
vector<int> ans;
void find(int o = root, int d = 0) {
  if (sx <= t[o].d[0] && t[o].d[0] <= tx && sy <= t[o].d[1] && t[o].d[1] <= ty)
    ans.push_back(t[o].num);
  if (d == 0) {
    if (t[o].l && sx <= t[o][0])
      find(t[o].l, d ^ 1);
    if (t[o].r && t[o][0] <= tx)
      find(t[o].r, d ^ 1);
  } else {
    if (t[o].l && sy <= t[o][1])
      find(t[o].l, d ^ 1);
    if (t[o].r && t[o][1] <= ty)
      find(t[o].r, d ^ 1);
  }
}
int main() {
  read(n);
  for (int i = 0; i < n; ++i)
    read(P[i][0], P[i][1]), P[i].num = i;
  root = build();
  int q;
  read(q);
  while (q--) {
    ans.clear();
    read(sx, tx), read(sy, ty);
    find();
    sort(ans.begin(), ans.end());
    for (int i = 0; i < ans.size(); ++i)
      printf("%d\\n", ans[i]);
    puts("");
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <set>
#define MAXN 500005
using namespace std;
inline long long sq(long long x) { return x * x; }
namespace KDTree {
struct Point {
  int x, y;
  int index;
  long long distance(const Point &b) const { return sq(x - b.x) + sq(y - b.y); }
  bool in(const Point &a, const Point &b) const {
    return a.x <= x && x <= b.x && a.y <= y && y <= b.y;
  }
};
inline bool cmpX(const Point &a, const Point &b) {
  return a.x < b.x || (a.x == b.x && a.y < b.y) ||
         (a.x == b.x && a.y == b.y && a.index < b.index);
}
inline bool cmpY(const Point &a, const Point &b) {
  return a.y < b.y || (a.y == b.y && a.x < b.x) ||
         (a.y == b.y && a.x == b.x && a.index < b.index);
}
bool cmp(const Point &a, const Point &b, bool div) {
  return div ? cmpY(a, b) : cmpX(a, b);
}
struct Node {
  Point e;
  Node *lc, *rc;
  bool div;
} pool[MAXN], *tail, *root;
void init() { tail = pool; }
Node *build(Point *a, int l, int r, bool div) {
  if (l >= r)
    return NULL;
  Node *p = tail++;
  p->div = div;
  int mid = (l + r) / 2;
  nth_element(a + l, a + mid, a + r, div ? cmpY : cmpX);
  p->e = a[mid];
  p->lc = build(a, l, mid, !div);
  p->rc = build(a, mid + 1, r, !div);
  return p;
}
int ans[105], ans_cnt = 0;
void RangeQuery(Node *node, Point &L, Point &R) {
  if (node == NULL)
    return;
  if (node->e.in(L, R))
    ans[ans_cnt++] = node->e.index;
  if (!node->div) {
    if (node->e.x >= L.x) {
      RangeQuery(node->lc, L, R);
    }
    if (node->e.x <= R.x) {
      RangeQuery(node->rc, L, R);
    }
  } else {
    if (node->e.y >= L.y) {
      RangeQuery(node->lc, L, R);
    }
    if (node->e.y <= R.y) {
      RangeQuery(node->rc, L, R);
    }
  }
}
}; // namespace KDTree

KDTree::Point r[MAXN];

int main() {
  cin.tie(0);
  cin.sync_with_stdio(0);
  int n;
  cin >> n;
  int x, y;
  for (int i = 0; i < n; ++i) {
    cin >> x >> y;
    r[i].x = x;
    r[i].y = y;
    r[i].index = i;
  }
  KDTree::init();
  KDTree::root = KDTree::build(r, 0, n, 0);
  int q;
  cin >> q;
  int sx, tx, sy, ty;
  while (q--) {
    KDTree::ans_cnt = 0;
    cin >> sx >> tx >> sy >> ty;
    KDTree::Point L, R;
    L.x = sx;
    L.y = sy;
    R.x = tx;
    R.y = ty;
    RangeQuery(KDTree::root, L, R);
    sort(KDTree::ans, KDTree::ans + KDTree::ans_cnt);
    for (int i = 0; i < KDTree::ans_cnt; ++i) {
      cout << KDTree::ans[i] << endl;
    }
    cout << endl;
  }
}