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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;
#define MAX_N 500005
#define MAX_Q 20010
#define MAX_L 40010

struct data {
  int y, id;
  bool operator<(const data &p) const {
    return (y == p.y ? id < p.id : y < p.y);
  }
};

int n;
int px[MAX_N], py[MAX_N];
int ax[MAX_Q], ay[MAX_Q];
int bx[MAX_Q], by[MAX_Q];

set<data> t[500];
set<data> u[MAX_L];

void Set(int x, int y, int id) {
  u[x].insert((data){y, id});
  t[x / 500].insert((data){y, id});
}
vector<int> ans;
void Find(int ax, int ay, int bx, int by) {
  set<data>::iterator it;
  for (int i = ax; i < bx; i++) {
    if (i % 500 == 0 && i + 500 <= bx) {
      it = t[i / 500].lower_bound((data){ay, -1});
      while (1) {
        if (it == t[i / 500].end() || by < it->y)
          break;
        ans.push_back(it->id);
        it++;
      }
      i += 499;
    } else {
      it = u[i].lower_bound((data){ay, -1});
      while (1) {
        if (it == u[i].end() || by < it->y)
          break;
        ans.push_back(it->id);
        it++;
      }
    }
  }
}

int tx[MAX_L];
int ux[MAX_L];
int size = 0;

int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++)
    scanf("%d %d", &px[i], &py[i]);

  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d %d %d %d", &ax[i], &bx[i], &ay[i], &by[i]);
    bx[i]++;
    tx[size++] = ax[i];
    tx[size++] = bx[i];
  }
  tx[size++] = 1e9 + 2;
  tx[size++] = -1e9 - 2;
  sort(tx, tx + size);
  ux[0] = 1;
  for (int i = 1; i < size; i++)
    ux[i] = ux[i - 1] + (tx[i] != tx[i - 1]);
  for (int i = 0; i < n; i++) {
    px[i] = ux[upper_bound(tx, tx + size, px[i]) - tx - 1];
    Set(px[i], py[i], i);
  }

  for (int i = 0; i < q; i++) {
    ans.clear();
    ax[i] = ux[lower_bound(tx, tx + size, ax[i]) - tx];
    bx[i] = ux[lower_bound(tx, tx + size, bx[i]) - tx];

    Find(ax[i], ay[i], bx[i], by[i]);
    sort(ans.begin(), ans.end());
    for (int i = 0; i < (int)ans.size(); i++) {
      if (i && ans[i] == ans[i - 1])
        continue;
      printf("%d\\n", ans[i]);
    }
    printf("\\n");
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;
#define MAX_N 500005
#define MAX_Q 20005
#define MAX_L 40005

struct data {
  int y, id;
  bool operator<(const data &p) const {
    return (y == p.y ? id < p.id : y < p.y);
  }
};

int n;
int px[MAX_N], py[MAX_N];
int ax[MAX_Q], ay[MAX_Q];
int bx[MAX_Q], by[MAX_Q];

set<data> t[(1 << 17)];

void Set(int x, int y, int id) {
  x = x + (1 << 16) - 1;
  while (1) {
    t[x].insert((data){y, id});
    if (x == 0)
      break;
    x = (x - 1) / 2;
  }
}

vector<int> ans;
void find(int ax, int ay, int bx, int by, int k = 0, int l = 0,
          int r = (1 << 16)) {

  if (bx <= l || r <= ax)
    return;

  if (ax <= l && r <= bx) {
    set<data>::iterator it = t[k].lower_bound((data){ay, -1});
    while (1) {
      if (it == t[k].end() || by < it->y)
        break;
      ans.push_back(it->id);
      it++;
    }
  } else {
    find(ax, ay, bx, by, k * 2 + 1, l, (l + r) / 2);
    find(ax, ay, bx, by, k * 2 + 2, (l + r) / 2, r);
  }
}

int tx[MAX_L];
int ux[MAX_L];
int size = 0;

int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++)
    scanf("%d %d", &px[i], &py[i]);

  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d %d %d %d", &ax[i], &bx[i], &ay[i], &by[i]);
    ax[i]--;
    tx[size++] = ax[i];
    tx[size++] = bx[i];
  }
  tx[size++] = 1e9;
  sort(tx, tx + size);
  ux[0] = 1;
  for (int i = 1; i < size; i++) {
    if (tx[i] == tx[i - 1])
      ux[i] = ux[i - 1];
    else
      ux[i] = ux[i - 1] + 1;
  }

  for (int i = 0; i < n; i++) {
    px[i] = ux[lower_bound(tx, tx + size, px[i]) - tx];
    Set(px[i], py[i], i);
  }

  for (int i = 0; i < q; i++) {
    ans.clear();
    ax[i] = ux[lower_bound(tx, tx + size, ax[i]) - tx];
    bx[i] = ux[lower_bound(tx, tx + size, bx[i]) - tx];

    find(ax[i] + 1, ay[i], bx[i] + 1, by[i]);

    sort(ans.begin(), ans.end());
    for (int i = 0; i < (int)ans.size(); i++) {
      if (i && ans[i] == ans[i - 1])
        continue;
      printf("%d\\n", ans[i]);
    }
    printf("\\n");
  }
  return 0;
}