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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define dow(i, a, b) for (int i = a; i >= b; --i)
#define mem(a) memset(a, 0, sizeof(a))
#define mst(a, b) memset(a, b, sizeof(a))
#define sfi(a) scanf("%d", &a)
#define sfl(a) scanf("%lld", &a)
#define sfd(a) scanf("%lf", &a)
#define sfs(a) scanf("%s", a)
#define pb(a) push_back(a)
#define sync                                                                   \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);

const int MAXN = 1000 + 5;
const double EPS = 1e-6;
const double PI = acos(-1.0);

typedef struct Point Point;
typedef struct Line Line;
typedef struct Polygon Polygon;
typedef struct Polygon_convex Polygon_convex;

int cmp(double x);
double sqr(double x);
double det(Point a, Point b);
double dot(Point a, Point b);
double dist(Point a, Point b);
Point rotate_point(Point p, double A);
bool parallel(Line a, Line b);
bool orthogonal(Line a, Line b);
Point PointProjLine(Point p, Line l, Point &ans);
Point reflect(Line l, Point p);
double dis_point_segment(Point p, Line l);
double dis_segment_segment(Line a, Line b);
Line point_make_line(Point a, Point b);
bool in_segment(Line l, Point p);
int dcmp(double k);
double mysqrt(double n);
Point rotate(Point p, double cost, double sint);
pair<Point, Point> crosspoint(Point ap, double ar, Point bp, double br);
bool PointOnSegment(Point p, Point s, Point t);
bool comp_less(Point a, Point b);
void convex_hull(vector<Point> a);

struct Point {
  double x, y;
  Point() {}
  Point(double a, double b) : x(a), y(b) {}

  friend Point operator-(Point a, Point b) {
    return Point(a.x - b.x, a.y - b.y);
  }
  friend Point operator+(Point a, Point b) {
    return Point(a.x + b.x, a.y + b.y);
  }
  friend bool operator==(Point a, Point b) {
    return cmp(a.x - b.x) == 0 && cmp(a.y - b.y) == 0;
  }
  friend Point operator*(Point a, double b) { return Point(a.x * b, a.y * b); }
  friend Point operator*(double a, Point b) { return Point(a * b.x, a * b.y); }
  friend Point operator/(Point a, double b) { return Point(a.x / b, a.y / b); }
  double norm() { return sqrt(sqr(x) + sqr(y)); }
};

struct Line {
  Point a, b;
  Line() {}
  Line(Point x, Point y) : a(x), b(y) {}
};

struct Polygon {
  int n;
  Point a[MAXN];
  Polygon() {}
  int Point_In(Point t) {
    int num = 0;
    a[n] = a[0];
    rep(i, 0, n - 1) {
      if (PointOnSegment(t, a[i], a[i + 1]))
        return 2;
      int k = cmp(det(a[i + 1] - a[i], t - a[i]));
      int d1 = cmp(a[i].y - t.y);
      int d2 = cmp(a[i + 1].y - t.y);
      if (k > 0 && d1 <= 0 && d2 > 0)
        num++;
      if (k < 0 && d2 <= 0 && d1 > 0)
        num--;
    }
    return num != 0;
  }
};

struct Polygon_convex {
  vector<Point> P;
  Polygon_convex(int Size = 0) { P.resize(Size); }
} res(2 * 100000 + 50);

bool comp_less(Point a, Point b) {
  return cmp(a.x - b.x) < 0 || cmp(a.x - b.x) == 0 && cmp(a.y - b.y) < 0;
}

void convex_hull(vector<Point> a) {
  sort(a.begin(), a.end(), comp_less);
  a.erase(unique(a.begin(), a.end()), a.end());
  int m = 0;
  int len = a.size();
  rep(i, 0, len - 1) {
    while (m > 1 &&
           cmp(det(res.P[m - 1] - res.P[m - 2], a[i] - res.P[m - 2])) < 0)
      --m;
    res.P[m++] = a[i];
  }
  int k = m;
  len = a.size();
  dow(i, len - 2, 0) {
    while (m > k &&
           cmp(det(res.P[m - 1] - res.P[m - 2], a[i] - res.P[m - 2])) < 0)
      --m;
    res.P[m++] = a[i];
  }
  res.P.resize(m);
  if (a.size() > 1)
    res.P.resize(m - 1);
}

bool PointOnSegment(Point p, Point s, Point t) {
  return cmp(det(p - s, t - s)) == 0 && cmp(dot(p - s, p - t)) <= 0;
}

bool parallel(Line a, Line b) { return !cmp(det(a.a - a.b, b.a - b.b)); }

bool orthogonal(Line a, Line b) { return !cmp(dot(a.a - a.b, b.a - b.b)); }

Point PointProjLine(Point p, Line l) {
  Point ans;
  double r = dot((l.b - l.a), (p - l.a)) / dot(l.b - l.a, l.b - l.a);
  ans = l.a + r * (l.b - l.a);
  return ans;
}

int cmp(double x) {
  if (abs(x) < EPS)
    return 0;
  if (x > 0)
    return 1;
  return -1;
}

double dis_point_segment(Point p, Line l) {
  if (cmp(dot(p - l.a, l.b - l.a)) < 0)
    return (p - l.a).norm();
  if (cmp(dot(p - l.b, l.a - l.b)) < 0)
    return (p - l.b).norm();
  return abs(det(l.a - p, l.b - p)) / dist(l.a, l.b);
}

bool line_make_point(Line a, Line b, Point &res) {
  if (parallel(a, b))
    return false;
  double s1 = det(a.a - b.a, b.b - b.a);
  double s2 = det(a.b - b.a, b.b - b.a);
  res = (s1 * a.b - s2 * a.a) / (s1 - s2);
  return true;
}

double dis_segment_segment(Line a, Line b) {
  Point res;
  if (line_make_point(a, b, res) && in_segment(a, res) && in_segment(b, res))
    return 0.;
  return min(min(dis_point_segment(b.a, a), dis_point_segment(b.b, a)),
             min(dis_point_segment(a.a, b), dis_point_segment(a.b, b)));
}

double sqr(double x) { return x * x; }

double det(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double dist(Point a, Point b) { return (a - b).norm(); }

Point rotate_point(Point p, double A) {
  double tx = p.x, ty = p.y;
  return Point(tx * cos(A) - ty * sin(A), tx * sin(A) + ty * cos(A));
}

Point reflect(Line l, Point p) { return p + ((PointProjLine(p, l) - p) * 2.0); }

bool in_segment(Line l, Point p) {
  bool fa = false, fb = false;
  if ((cmp(p.x - l.a.x) != -1 && cmp(p.x - l.b.x) != 1) ||
      (cmp(p.x - l.a.x) != 1 && cmp(p.x - l.b.x) != -1))
    fa = true;
  if ((cmp(p.y - l.a.y) != -1 && cmp(p.y - l.b.y) != 1) ||
      (cmp(p.y - l.a.y) != 1 && cmp(p.y - l.b.y) != -1))
    fb = true;
  return fa && fb;
}

int dcmp(double k) { return k < -EPS ? -1 : k > EPS ? 1 : 0; }

double mysqrt(double n) { return sqrt(max(0.0, n)); }

void circle_cross_line(Point a, Point b, Point o, double r, Point ret[],
                       int &num) {
  double x0 = o.x, y0 = o.y;
  double x1 = a.x, y1 = a.y;
  double x2 = b.x, y2 = b.y;
  double dx = x2 - x1, dy = y2 - y1;
  double A = dx * dx + dy * dy;
  double B = 2 * dx * (x1 - x0) + 2 * dy * (y1 - y0);
  double C = sqr(x1 - x0) + sqr(y1 - y0) - sqr(r);
  double delta = B * B - 4 * A * C;
  num = 0;
  if (dcmp(delta) >= 0) {
    double t1 = (-B - mysqrt(delta)) / (2 * A);
    double t2 = (-B + mysqrt(delta)) / (2 * A);
    ret[num++] = Point(x1 + t1 * dx, y1 + t1 * dy);
    ret[num++] = Point(x1 + t2 * dx, y1 + t2 * dy);
  }
}

Point rotate(Point p, double cost, double sint) {
  double x = p.x, y = p.y;
  return Point(x * cost - y * sint, x * sint + y * cost);
}

pair<Point, Point> crosspoint(Point ap, double ar, Point bp, double br) {
  double d = (ap - bp).norm();
  double cost = (ar * ar + d * d - br * br) / (2 * ar * d);
  double sint = sqrt(1. - cost * cost);
  Point v = (bp - ap) / (bp - ap).norm() * ar;
  return make_pair(ap + rotate(v, cost, -sint), ap + rotate(v, cost, sint));
}

const int L = 2;
const LL MOD = 100000 + 50;
const int MAX = 100000 + 50;

struct Pointt {
  int x, y;
  Pointt(int xx = 0, int yy = 0) : x(xx), y(yy) {}
};

struct Node {
  Pointt p;
  Pointt q;
  int id;
  Node(Pointt p_ = Pointt(0, 0), Pointt q_ = Pointt(0, 0), int id_ = 4)
      : p(p_), q(q_), id(id_) {}
  friend bool operator==(Node a, Node b) {
    return a.p.x == b.p.x && a.p.y == b.p.y;
  }
  friend bool operator<(Node a, Node b) {
    if (a.p.y == b.p.y)
      return a.id < b.id;
    return a.p.y < b.p.y;
  }
} node[MAX * 2];

set<int> s;

int main() {
#ifdef LOCAL
  //~ freopen("in.txt", "r", stdin);
#endif

  int n;
  sfi(n);
  int cnt = 0;
  rep(i, 0, n - 1) {
    Pointt a, b;
    scanf("%d%d%d%d", &a.x, &a.y, &b.x, &b.y);
    if (cmp(a.x - b.x) == 0) {
      if (a.y < b.y) {
        node[cnt++] = Node(a, Pointt(0, 0), 1);
        node[cnt++] = Node(b, Pointt(0, 0), 3);
      } else {
        node[cnt++] = Node(a, Pointt(0, 0), 3);
        node[cnt++] = Node(b, Pointt(0, 0), 1);
      }
    } else {
      if (a.x < b.x)
        node[cnt++] = Node(a, b, 2);
      else
        node[cnt++] = Node(b, a, 2);
    }
  }
  sort(node, node + cnt);

  int ans = 0;
  rep(i, 0, cnt - 1) {
    if (node[i].id == 3) {
      set<int>::iterator it = s.find(node[i].p.x);
      s.erase(*it);
    } else if (node[i].id == 1) {
      s.insert(node[i].p.x);
    } else if (node[i].id == 2) {
      set<int>::iterator it = s.lower_bound(node[i].p.x);
      for (; (*it) <= node[i].q.x && it != s.end(); it++)
        ans++;
    }
  }
  printf("%d\\n", ans);
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define dow(i, a, b) for (int i = a; i >= b; --i)
#define mem(a) memset(a, 0, sizeof(a))
#define mst(a, b) memset(a, b, sizeof(a))
#define sfi(a) scanf("%d", &a)
#define sfl(a) scanf("%lld", &a)
#define sfd(a) scanf("%lf", &a)
#define sfs(a) scanf("%s", a)
#define pb(a) push_back(a)
#define sync                                                                   \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);

const int MAXN = 1000 + 5;
const double EPS = 1e-6;
const double PI = acos(-1.0);

typedef struct Point Point;
typedef struct Line Line;
typedef struct Polygon Polygon;
typedef struct Polygon_convex Polygon_convex;

int cmp(double x);
double sqr(double x);
double det(Point a, Point b);
double dot(Point a, Point b);
double dist(Point a, Point b);
Point rotate_point(Point p, double A);
bool parallel(Line a, Line b);
bool orthogonal(Line a, Line b);
Point PointProjLine(Point p, Line l, Point &ans);
Point reflect(Line l, Point p);
double dis_point_segment(Point p, Line l);
double dis_segment_segment(Line a, Line b);
Line point_make_line(Point a, Point b);
bool in_segment(Line l, Point p);
int dcmp(double k);
double mysqrt(double n);
Point rotate(Point p, double cost, double sint);
pair<Point, Point> crosspoint(Point ap, double ar, Point bp, double br);
bool PointOnSegment(Point p, Point s, Point t);
bool comp_less(Point a, Point b);
void convex_hull(vector<Point> a);

struct Point {
  double x, y;
  Point() {}
  Point(double a, double b) : x(a), y(b) {}

  friend Point operator-(Point a, Point b) {
    return Point(a.x - b.x, a.y - b.y);
  }
  friend Point operator+(Point a, Point b) {
    return Point(a.x + b.x, a.y + b.y);
  }
  friend bool operator==(Point a, Point b) {
    return cmp(a.x - b.x) == 0 && cmp(a.y - b.y) == 0;
  }
  friend Point operator*(Point a, double b) { return Point(a.x * b, a.y * b); }
  friend Point operator*(double a, Point b) { return Point(a * b.x, a * b.y); }
  friend Point operator/(Point a, double b) { return Point(a.x / b, a.y / b); }
  double norm() { return sqrt(sqr(x) + sqr(y)); }
};

struct Line {
  Point a, b;
  Line() {}
  Line(Point x, Point y) : a(x), b(y) {}
};

struct Polygon {
  int n;
  Point a[MAXN];
  Polygon() {}
  int Point_In(Point t) {
    int num = 0;
    a[n] = a[0];
    rep(i, 0, n - 1) {
      if (PointOnSegment(t, a[i], a[i + 1]))
        return 2;
      int k = cmp(det(a[i + 1] - a[i], t - a[i]));
      int d1 = cmp(a[i].y - t.y);
      int d2 = cmp(a[i + 1].y - t.y);
      if (k > 0 && d1 <= 0 && d2 > 0)
        num++;
      if (k < 0 && d2 <= 0 && d1 > 0)
        num--;
    }
    return num != 0;
  }
};

struct Polygon_convex {
  vector<Point> P;
  Polygon_convex(int Size = 0) { P.resize(Size); }
} res(2 * 100000 + 50);

bool comp_less(Point a, Point b) {
  return cmp(a.x - b.x) < 0 || cmp(a.x - b.x) == 0 && cmp(a.y - b.y) < 0;
}

void convex_hull(vector<Point> a) {
  sort(a.begin(), a.end(), comp_less);
  a.erase(unique(a.begin(), a.end()), a.end());
  int m = 0;
  int len = a.size();
  rep(i, 0, len - 1) {
    while (m > 1 &&
           cmp(det(res.P[m - 1] - res.P[m - 2], a[i] - res.P[m - 2])) < 0)
      --m;
    res.P[m++] = a[i];
  }
  int k = m;
  len = a.size();
  dow(i, len - 2, 0) {
    while (m > k &&
           cmp(det(res.P[m - 1] - res.P[m - 2], a[i] - res.P[m - 2])) < 0)
      --m;
    res.P[m++] = a[i];
  }
  res.P.resize(m);
  if (a.size() > 1)
    res.P.resize(m - 1);
}

bool PointOnSegment(Point p, Point s, Point t) {
  return cmp(det(p - s, t - s)) == 0 && cmp(dot(p - s, p - t)) <= 0;
}

bool parallel(Line a, Line b) { return !cmp(det(a.a - a.b, b.a - b.b)); }

bool orthogonal(Line a, Line b) { return !cmp(dot(a.a - a.b, b.a - b.b)); }

Point PointProjLine(Point p, Line l) {
  Point ans;
  double r = dot((l.b - l.a), (p - l.a)) / dot(l.b - l.a, l.b - l.a);
  ans = l.a + r * (l.b - l.a);
  return ans;
}

int cmp(double x) {
  if (abs(x) < EPS)
    return 0;
  if (x > 0)
    return 1;
  return -1;
}

double dis_point_segment(Point p, Line l) {
  if (cmp(dot(p - l.a, l.b - l.a)) < 0)
    return (p - l.a).norm();
  if (cmp(dot(p - l.b, l.a - l.b)) < 0)
    return (p - l.b).norm();
  return abs(det(l.a - p, l.b - p)) / dist(l.a, l.b);
}

bool line_make_point(Line a, Line b, Point &res) {
  if (parallel(a, b))
    return false;
  double s1 = det(a.a - b.a, b.b - b.a);
  double s2 = det(a.b - b.a, b.b - b.a);
  res = (s1 * a.b - s2 * a.a) / (s1 - s2);
  return true;
}

double dis_segment_segment(Line a, Line b) {
  Point res;
  if (line_make_point(a, b, res) && in_segment(a, res) && in_segment(b, res))
    return 0.;
  return min(min(dis_point_segment(b.a, a), dis_point_segment(b.b, a)),
             min(dis_point_segment(a.a, b), dis_point_segment(a.b, b)));
}

double sqr(double x) { return x * x; }

double det(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double dist(Point a, Point b) { return (a - b).norm(); }

Point rotate_point(Point p, double A) {
  double tx = p.x, ty = p.y;
  return Point(tx * cos(A) - ty * sin(A), tx * sin(A) + ty * cos(A));
}

Point reflect(Line l, Point p) { return p + ((PointProjLine(p, l) - p) * 2.0); }

bool in_segment(Line l, Point p) {
  bool fa = false, fb = false;
  if ((cmp(p.x - l.a.x) != -1 && cmp(p.x - l.b.x) != 1) ||
      (cmp(p.x - l.a.x) != 1 && cmp(p.x - l.b.x) != -1))
    fa = true;
  if ((cmp(p.y - l.a.y) != -1 && cmp(p.y - l.b.y) != 1) ||
      (cmp(p.y - l.a.y) != 1 && cmp(p.y - l.b.y) != -1))
    fb = true;
  return fa && fb;
}

int dcmp(double k) { return k < -EPS ? -1 : k > EPS ? 1 : 0; }

double mysqrt(double n) { return sqrt(max(0.0, n)); }

void circle_cross_line(Point a, Point b, Point o, double r, Point ret[],
                       int &num) {
  double x0 = o.x, y0 = o.y;
  double x1 = a.x, y1 = a.y;
  double x2 = b.x, y2 = b.y;
  double dx = x2 - x1, dy = y2 - y1;
  double A = dx * dx + dy * dy;
  double B = 2 * dx * (x1 - x0) + 2 * dy * (y1 - y0);
  double C = sqr(x1 - x0) + sqr(y1 - y0) - sqr(r);
  double delta = B * B - 4 * A * C;
  num = 0;
  if (dcmp(delta) >= 0) {
    double t1 = (-B - mysqrt(delta)) / (2 * A);
    double t2 = (-B + mysqrt(delta)) / (2 * A);
    ret[num++] = Point(x1 + t1 * dx, y1 + t1 * dy);
    ret[num++] = Point(x1 + t2 * dx, y1 + t2 * dy);
  }
}

Point rotate(Point p, double cost, double sint) {
  double x = p.x, y = p.y;
  return Point(x * cost - y * sint, x * sint + y * cost);
}

pair<Point, Point> crosspoint(Point ap, double ar, Point bp, double br) {
  double d = (ap - bp).norm();
  double cost = (ar * ar + d * d - br * br) / (2 * ar * d);
  double sint = sqrt(1. - cost * cost);
  Point v = (bp - ap) / (bp - ap).norm() * ar;
  return make_pair(ap + rotate(v, cost, -sint), ap + rotate(v, cost, sint));
}

const int L = 2;
const LL MOD = 100000 + 50;
const int MAX = 100000 + 50;

struct Node {
  Point p;
  Point q;
  int id;
  Node(Point p_ = Point(0., 0.), Point q_ = Point(0., 0.), int id_ = 4)
      : p(p_), q(q_), id(id_) {}
  friend bool operator==(Node a, Node b) {
    return cmp(a.p.x - b.p.x) == 0 && cmp(a.p.y - b.p.y) == 0;
  }
  friend bool operator<(Node a, Node b) {
    if (cmp(a.p.y - b.p.y) == 0)
      return a.id < b.id;
    return a.p.y < b.p.y;
  }
} node[MAX * 2];

set<double> s;

int main() {
#ifdef LOCAL
  //~ freopen("in.txt", "r", stdin);
#endif

  int n;
  sfi(n);
  int cnt = 0;
  rep(i, 0, n - 1) {
    Point a, b;
    scanf("%lf%lf%lf%lf", &a.x, &a.y, &b.x, &b.y);
    if (cmp(a.x - b.x) == 0) {
      if (a.y < b.y) {
        node[cnt++] = Node(a, Point(0., 0.), 1);
        node[cnt++] = Node(b, Point(0., 0.), 3);
      } else {
        node[cnt++] = Node(a, Point(0., 0.), 3);
        node[cnt++] = Node(b, Point(0., 0.), 1);
      }
    } else {
      if (a.x < b.x)
        node[cnt++] = Node(a, b, 2);
      else
        node[cnt++] = Node(b, a, 2);
    }
  }
  sort(node, node + cnt);

  int ans = 0;
  rep(i, 0, cnt - 1) {
    if (node[i].id == 3) {
      set<double>::iterator it = s.find(node[i].p.x);
      s.erase(*it);
    } else if (node[i].id == 1) {
      s.insert(node[i].p.x);
    } else if (node[i].id == 2) {
      set<double>::iterator it = s.lower_bound(node[i].p.x);
      set<double>::iterator iter = s.lower_bound(node[i].q.x);
      if (cmp((*iter) - node[i].q.x) == 0)
        iter++;
      for (; it != iter; it++)
        ans++;
    }
  }
  printf("%d\\n", ans);
  return 0;
}