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

#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;

class Node {
public:
  int location;
  int p, l, r;
  Node() {}
};

class Point {
public:
  int id, x, y;
  Point() {}
  Point(int id, int x, int y) : id(id), x(x), y(y) {}
  bool operator<(const Point &p) const { return id < p.id; }

  void print() { printf("%d\\n", id); }
};

static const int MAX = 1000000;
static const int NIL = -1;

int N;
Point P[MAX];
Node T[MAX];
int np;

bool lessX(const Point &p1, const Point &p2) { return p1.x < p2.x; }

bool lessY(const Point &p1, const Point &p2) { return p1.y < p2.y; }

int makeKDTree(int l, int r, int depth) {
  if (!(l < r))
    return NIL;
  int mid = (l + r) / 2;
  int t = np++;
  if (depth % 2 == 0) {
    sort(P + l, P + r, lessX);
  } else {
    sort(P + l, P + r, lessY);
  }
  T[t].location = mid;
  T[t].l = makeKDTree(l, mid, depth + 1);
  T[t].r = makeKDTree(mid + 1, r, depth + 1);

  return t;
}

void find(int v, int sx, int tx, int sy, int ty, int depth,
          vector<Point> &ans) {
  int x = P[T[v].location].x;
  int y = P[T[v].location].y;

  if (sx <= x && x <= tx && sy <= y && y <= ty) {
    ans.push_back(P[T[v].location]);
  }

  if (depth % 2 == 0) {
    if (T[v].l != NIL) {
      if (sx <= x)
        find(T[v].l, sx, tx, sy, ty, depth + 1, ans);
    }
    if (T[v].r != NIL) {
      if (x <= tx)
        find(T[v].r, sx, tx, sy, ty, depth + 1, ans);
    }
  } else {
    if (T[v].l != NIL) {
      if (sy <= y)
        find(T[v].l, sx, tx, sy, ty, depth + 1, ans);
    }
    if (T[v].r != NIL) {
      if (y <= ty)
        find(T[v].r, sx, tx, sy, ty, depth + 1, ans);
    }
  }
}

int main() {
  int x, y;
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scanf("%d %d", &x, &y);
    P[i] = Point(i, x, y);
    T[i].l = T[i].r = T[i].p = NIL;
  }

  np = 0;

  int root = makeKDTree(0, N, 0);

  int q;
  scanf("%d", &q);
  int sx, tx, sy, ty;
  vector<Point> ans;
  for (int i = 0; i < q; i++) {
    scanf("%d %d %d %d", &sx, &tx, &sy, &ty);
    ans.clear();
    find(root, sx, tx, sy, ty, 0, ans);
    sort(ans.begin(), ans.end());
    for (unsigned int j = 0; j < ans.size(); j++) {
      ans[j].print();
    }
    printf("\\n");
  }

  return 0;
}

Error: TLE

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <list>
#include <queue>
#include <string>
#include <vector>

using namespace std;

struct Coordinate {
  int ID;
  int Value;
};

vector<Coordinate> X, Y;
int N;

void indicesInTheRangeForX(int s, int t, int *index1, int *index2) {
  int f = 0;
  int r = N - 1;
  int m;

  if (X[r].Value < s) {
    *index1 = *index2 = -1;
    return;
  }

  if (t < X[f].Value) {
    *index1 = *index2 = -1;
    return;
  }

  while (f <= r) {
    m = (f + r) / 2;
    if (s <= X[m].Value) {
      if (m == 0 || X[m - 1].Value < s) {
        *index1 = m;
        break;
      } else {
        r = m - 1;
        continue;
      }
    } else {
      f = m + 1;
      continue;
    }
  }
  if (r < f) {
    // not found
    // impossible case
    printf("Something wrong X1\\n");
  }

  f = m;
  r = N - 1;
  while (f <= r) {
    m = (f + r) / 2;
    if (X[m].Value <= t) {
      if (m == N - 1 || t < X[m + 1].Value) {
        *index2 = m;
        break;
      } else {
        f = m + 1;
        continue;
      }
    } else {
      r = m - 1;
      continue;
    }
  }
  if (r < f) {
    *index1 = *index2 = -1;
    ////not found
    ////impossible case
    // printf("Something wrong X2\\n");
    //
    ////DEBUG
    // printf("[s, t] = [%d, %d]\\n", s, t);
    // for (int i = 0; i < N; i++) {
    //	printf("%d ", X[i].Value);
    // }
    // printf("\\n");
  }
}

void indicesInTheRangeForY(int s, int t, int *index1, int *index2) {
  int f = 0;
  int r = N - 1;
  int m;

  if (Y[r].Value < s) {
    *index1 = *index2 = -1;
    return;
  }

  if (t < Y[f].Value) {
    *index1 = *index2 = -1;
    return;
  }

  while (f <= r) {
    m = (f + r) / 2;
    if (s <= Y[m].Value) {
      if (m == 0 || Y[m - 1].Value < s) {
        *index1 = m;
        break;
      } else {
        r = m - 1;
        continue;
      }
    } else {
      f = m + 1;
      continue;
    }
  }
  if (r < f) {
    // not found
    // impossible case
    printf("Something wrong Y1\\n");
  }

  f = m;
  r = N - 1;
  while (f <= r) {
    m = (f + r) / 2;
    if (Y[m].Value <= t) {
      if (m == N - 1 || t < Y[m + 1].Value) {
        *index2 = m;
        break;
      } else {
        f = m + 1;
        continue;
      }
    } else {
      r = m - 1;
      continue;
    }
  }
  if (r < f) {
    *index1 = *index2 = -1;
  }
}

bool binarySearch(int index1forX, int index2forX, int ID) {
  int f = index1forX;
  int r = index2forX;
  int m;

  while (f <= r) {
    m = (f + r) / 2;
    if (X[m].ID == ID) {
      return true;
    } else if (ID < X[m].ID) {
      r = m - 1;
    } else {
      f = m + 1;
    }
  }
  return false;
}

bool byID(const Coordinate &x, const Coordinate &y) { return x.ID < y.ID; }

bool byValue(const Coordinate &x, const Coordinate &y) {
  return x.Value < y.Value;
}

void printPointIDInTheRange(int sx, int tx, int sy, int ty) {
  int index1forX, index2forX;
  int index1forY, index2forY;
  indicesInTheRangeForX(sx, tx, &index1forX, &index2forX);
  indicesInTheRangeForY(sy, ty, &index1forY, &index2forY);
  if (index1forX == -1) {
    printf("\\n");
    return;
  }
  if (index1forY == -1) {
    printf("\\n");
    return;
  }

  // DEBUG
  // printf("index1forX = %d, index2forX = %d\\n", index1forX, index2forX);
  // if (index1forX == -1) {
  //	printf("\\n");
  //	return;
  // }
  // printf("index1forY = %d, index2forY = %d\\n", index1forY, index2forY);
  // if (index1forY == -1) {
  //	printf("\\n");
  //	return;
  // }

  // sort(X.begin() + index1forX, X.begin() + index2forX + 1, [](const
  // Coordinate& x, const Coordinate& y) {return x.ID < y.ID; }); sort(Y.begin()
  // + index1forY, Y.begin() + index2forY + 1, [](const Coordinate& x, const
  // Coordinate& y) {return x.ID < y.ID; });
  sort(X.begin() + index1forX, X.begin() + index2forX + 1, byID);
  sort(Y.begin() + index1forY, Y.begin() + index2forY + 1, byID);

  for (int i = index1forY; i <= index2forY; i++) {
    if (binarySearch(index1forX, index2forX, Y[i].ID) == true) {
      printf("%d\\n", Y[i].ID);
    }
  }
  printf("\\n");

  // sort(X.begin() + index1forX, X.begin() + index2forX + 1, [](const
  // Coordinate& x, const Coordinate& y) {return x.Value < y.Value; });
  // sort(Y.begin() + index1forY, Y.begin() + index2forY + 1, [](const
  // Coordinate& x, const Coordinate& y) {return x.Value < y.Value; });
  sort(X.begin() + index1forX, X.begin() + index2forX + 1, byValue);
  sort(Y.begin() + index1forY, Y.begin() + index2forY + 1, byValue);
}

int main() {
  int q;
  int sx, tx, sy, ty;
  // int index1, index2;
  scanf("%d", &N);
  X.resize(N);
  Y.resize(N);

  for (int i = 0; i < N; i++) {
    X[i].ID = Y[i].ID = i;
    scanf("%d %d", &(X[i].Value), &(Y[i].Value));
  }

  // sort(X.begin(), X.end(), [](const Coordinate& x, const Coordinate& y)
  // {return x.Value < y.Value; }); sort(Y.begin(), Y.end(), [](const
  // Coordinate& x, const Coordinate& y) {return x.Value < y.Value; });
  sort(X.begin(), X.end(), byValue);
  sort(Y.begin(), Y.end(), byValue);

  // for (unsigned int i = 0; i < X.size(); i++) {
  //	printf("%d\\n", X[i].Value);
  // }

  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d %d %d %d", &sx, &tx, &sy, &ty);

    ////DEBUG
    // for (int j = 0; j < N; j++) {
    //	cout << X[j].Value << " ";
    // }
    // cout << endl;

    printPointIDInTheRange(sx, tx, sy, ty);
    // indicesInTheRangeForX(sx, tx, &index1, &index2);
    // printf("[%d, %d]\\n", index1, index2);
  }

  return 0;
}

// int main() {
//	vector<Coordinate> X;
//	X.resize(5);
//	X[0].ID = 0;
//	X[1].ID = 2;
//	X[2].ID = 4;
//	X[3].ID = 6;
//	X[4].ID = 8;
//
//	X[0].Value = 3;
//	X[1].Value = 2;
//	X[2].Value = 5;
//	X[3].Value = 1;
//	X[4].Value = 4;
//
//
//	//sort(X.begin() + 1, X.begin() + 4, [](const Coordinate& x, const
//Coordinate& y) {return x.Value < y.Value; });
//	////sort(X.begin(), X.end(), [](const Coordinate& x, const Coordinate&
//y) {return x.Value < y.Value; });
//	//for (int i = 0; i < X.size(); i++) {
//	//	cout << X[i].Value << " ";
//	//}
//	//cout << endl;
//
//	Coordinate T;
//	T.Value = dummy integer;
//	T.ID = 1;
//
//	if (binary_search(X.begin(), X.end(), T, [](const Coordinate& x, const
//Coordinate& y) {return x.ID < y.ID; }) == true) { 		cout << "FOUND" << endl;
//	}
//	else {
//		cout << "NOT FOUND" << endl;
//	}
//
//	return 0;
// }

// int main() {
//	X.resize(6);
//	N = 6;
//	X[0].Value = 2;
//	X[1].Value = 2;
//	X[2].Value = 3;
//	X[3].Value = 4;
//	X[4].Value = 5;
//	X[5].Value = 6;
//	int index1, index2;
//	indicesInTheRangeForX(4, 10, &index1, &index2);
//	printf("[%d, %d]\\n", index1, index2);
//	return 0;
// }