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

#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

enum POSITION {
  ONLINE_BACK = -2,
  CCW = -1,
  ON_SEGMENT = 0,
  CW = 1,
  ONLINE_FRONT = 2
};

struct Point {
  long x;
  long y;
  Point(long x, long y) : x(x), y(y) {}
  Point() {}
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
};
typedef Point Vector;
double cross(Vector v1, Vector v2) { return v1.x * v2.y - v1.y * v2.x; }
double dot(Vector v1, Vector v2) { return v1.x * v2.x + v1.y * v2.y; }

struct Segment {
  Point p1;
  Point p2;
  Segment(Point p1, Point p2) : p1(p1), p2(p2) {}
  Segment() {}
};
typedef vector<Point> Polygon;

POSITION get_position(Segment s, Point p) {
  double c = cross(s.p2 - s.p1, p - s.p1);
  if (c > 0)
    return CCW;
  if (c < 0)
    return CW;
  double d = dot(s.p2 - s.p1, p - s.p1);
  if (d < 0)
    return ONLINE_BACK;
  if (d > dot(s.p2 - s.p1, s.p2 - s.p1))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool intersect(Segment s1, Segment s2) {
  if (get_position(s1, s2.p1) * get_position(s1, s2.p2) != -1) {
    return false;
  }
  if (get_position(s2, s1.p1) * get_position(s2, s1.p2) != -1) {
    return false;
  }
  return true;
}

int determine_containment(Point p, Polygon poly) {
  Segment s_right(p, Point(p.x + 1e5, p.y));
  int count = 0;
  for (int i = 0, n = poly.size(); i < n; i++) {
    if (get_position(Segment(poly[i], poly[(i + 1) % n]), p) == ON_SEGMENT) {
      return 1;
    }
    if (intersect(s_right, Segment(poly[i], poly[(i + 1) % n]))) {
      count++;
    }
    if (get_position(s_right, poly[i]) == ON_SEGMENT) {
      int i_pre = (i == 0 ? n - 1 : i - 1);
      POSITION pos_pre = get_position(s_right, poly[i_pre]);
      while (pos_pre != CCW && pos_pre != CW) {
        i_pre = (i_pre == 0 ? n - 1 : i_pre - 1);
        pos_pre = get_position(s_right, poly[i_pre]);
      }
      int i_aft = (i + 1) % n;
      POSITION pos_aft = get_position(s_right, poly[i_aft]);
      while (pos_aft != CCW && pos_aft != CW) {
        i_aft = (i_aft + 1) % n;
        pos_aft = get_position(s_right, poly[i_aft]);
      }
      if (get_position(s_right, poly[i_pre]) *
              get_position(s_right, poly[(i + 1) % n]) ==
          -1) {
        count++;
      }
    }
  }
  if (count % 2)
    return 2;
  return 0;
}
int main() {
  int q;
  cin >> q;
  Polygon poly(q);
  for (int i = 0; i < q; i++) {
    int x, y;
    cin >> x >> y;
    poly[i].x = x;
    poly[i].y = y;
  }
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    cout << determine_containment(Point(x, y), poly) << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

enum POSITION {
  ONLINE_BACK = -2,
  CCW = -1,
  ON_SEGMENT = 0,
  CW = 1,
  ONLINE_FRONT = 2
};

struct Point {
  long x;
  long y;
  Point(long x, long y) : x(x), y(y) {}
  Point() {}
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
};
typedef Point Vector;
double cross(Vector v1, Vector v2) { return v1.x * v2.y - v1.y * v2.x; }
double dot(Vector v1, Vector v2) { return v1.x * v2.x + v1.y * v2.y; }

struct Segment {
  Point p1;
  Point p2;
  Segment(Point p1, Point p2) : p1(p1), p2(p2) {}
  Segment() {}
};
typedef vector<Point> Polygon;

POSITION get_position(Segment s, Point p) {
  double c = cross(s.p2 - s.p1, p - s.p1);
  if (c > 0)
    return CCW;
  if (c < 0)
    return CW;
  double d = dot(s.p2 - s.p1, p - s.p1);
  if (d < 0)
    return ONLINE_BACK;
  if (d > dot(s.p2 - s.p1, s.p2 - s.p1))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool intersect(Segment s1, Segment s2) {
  if (get_position(s1, s2.p1) * get_position(s1, s2.p2) != -1) {
    return false;
  }
  if (get_position(s2, s1.p1) * get_position(s2, s1.p2) != -1) {
    return false;
  }
  return true;
}

int determine_containment(Point p, Polygon poly) {
  Segment s_right(p, Point(p.x + 1e5, p.y));
  int count = 0;
  for (int i = 0, n = poly.size(); i < n; i++) {
    if (get_position(Segment(poly[i], poly[(i + 1) % n]), p) == ON_SEGMENT) {
      return 1;
    }
    if (intersect(s_right, Segment(poly[i], poly[(i + 1) % n]))) {
      count++;
    }
    if (get_position(s_right, poly[i]) == ON_SEGMENT) {
      int i_pre = (i == 0 ? n - 1 : i - 1);
      POSITION pos_pre = get_position(s_right, poly[i_pre]);
      while (pos_pre != CCW && pos_pre != CW) {
        i_pre = (i_pre == 0 ? n - 1 : i_pre - 1);
        pos_pre = get_position(s_right, poly[i_pre]);
      }
      int i_aft = (i + 1) % n;
      POSITION pos_aft = get_position(s_right, poly[i_aft]);
      while (pos_aft != CCW && pos_aft != CW) {
        i_aft = (i_aft + 1) % n;
        POSITION pos_aft = get_position(s_right, poly[i_aft]);
      }
      if (get_position(s_right, poly[i_pre]) *
              get_position(s_right, poly[(i + 1) % n]) ==
          -1) {
        count++;
      }
    }
  }
  if (count % 2)
    return 2;
  return 0;
}
int main() {
  int q;
  cin >> q;
  Polygon poly(q);
  for (int i = 0; i < q; i++) {
    int x, y;
    cin >> x >> y;
    poly[i].x = x;
    poly[i].y = y;
  }
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    cout << determine_containment(Point(x, y), poly) << endl;
  }
  return 0;
}