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

#include <bits/stdc++.h>

#define PB push_back
#define PF push_front
#define MP make_pair
#define FI first
#define SE second
#define SIZE(A) int((A).size())
#define ALL(A) (A).begin(), (A).end()
#define ALLR(A) (A).rbegin(), (A).rend()

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long long lf;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<bool> vb;
typedef vector<lf> vd;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<pii> vpii;

const int MAXN = int(1e5) + 10;
const int MAXE = 2 * MAXN;
const int MOD = int(360);
const int oo = INT_MAX;

enum { OPEN, LINE, CLOSE };

struct pt {
  lf x, y;
  pt() {}
  pt(lf x, lf y) : x(x), y(y) {}
};

inline lf x(pt P) { return P.x; }
inline lf y(pt P) { return P.y; }

istream &operator>>(istream &in, pt &p) {
  lf x, y;
  in >> x >> y;
  p = pt(x, y);
  return in;
}

ostream &operator<<(ostream &out, const pt &p) {
  out << double(p.x) << " " << double(p.y);
  return out;
}

pt operator+(const pt &A, const pt &B) { return pt(x(A) + x(B), y(A) + y(B)); }

pt operator-(const pt &A, const pt &B) { return pt(x(A) - x(B), y(A) - y(B)); }

struct Event {
  int t;
  pt p, q;
  Event() {}
  Event(int t, pt p, pt q) : t(t), p(p), q(q) {}
};

bool cmp_Event(const Event &A, const Event &B) {
  if (A.p.x != B.p.x)
    return A.p.x < B.p.x;
  return A.t < B.t;
}

int n;
pt P[2][MAXN];
ll zip[2][2 * MAXN];
int bit[MAXN];
Event events[MAXE];

void add(int i) {
  for (; i < MAXN; i += (i & -i)) {
    ++bit[i];
  }
}

void erase(int i) {
  for (; i < MAXN; i += (i & -i)) {
    --bit[i];
  }
}

int query(int i) {
  int sum = 0;
  for (; i > 0; i -= (i & -i)) {
    sum += bit[i];
  }
  return sum;
}

int main() {

#ifdef LOCAL
  freopen("input", "r", stdin);
  // freopen( "output", "w", stdout );
#else
  // freopen( "input", "r", stdin );
  // freopen( "output", "w", stdout );
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#endif

  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> P[0][i] >> P[1][i];
    if (P[0][i].y > P[1][i].y)
      swap(P[0][i], P[1][i]);
    if (P[0][i].x > P[1][i].x)
      swap(P[0][i], P[1][i]);

    zip[0][i] = P[0][i].x;
    zip[0][i + n] = P[1][i].x;
    zip[1][i] = P[0][i].y;
    zip[1][i + n] = P[1][i].y;
  }
  sort(zip[0], zip[0] + 2 * n);
  sort(zip[1], zip[1] + 2 * n);
  int sz1 = distance(zip[0], unique(zip[0], zip[0] + 2 * n));
  int sz2 = distance(zip[1], unique(zip[1], zip[1] + 2 * n));

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < n; ++j) {
      P[i][j].x = lower_bound(zip[0], zip[0] + sz1, P[i][j].x) - zip[0] + 1;
      P[i][j].y = lower_bound(zip[1], zip[1] + sz2, P[i][j].y) - zip[1] + 1;
    }
  }
  int t = 0;
  for (int i = 0; i < n; ++i) {
    if (P[0][i].x == P[1][i].x) {
      events[t++] = Event(LINE, P[0][i], P[1][i]);
    } else {
      events[t++] = Event(OPEN, P[0][i], P[0][i]);
      events[t++] = Event(CLOSE, P[1][i], P[1][i]);
    }
  }
  int ans = 0;
  sort(events, events + t, cmp_Event);

  for (int i = 0; i < t; ++i) {
    Event &e = events[i];
    if (e.t == OPEN) {
      add(e.p.y);
    } else if (e.t == CLOSE) {
      erase(e.p.y);
    } else if (e.t == LINE) {
      ans += query(e.q.y) - query(e.p.y - 1);
    }
  }
  cout << ans << '\\n';
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define PB push_back
#define PF push_front
#define MP make_pair
#define FI first
#define SE second
#define SIZE(A) int((A).size())
#define ALL(A) (A).begin(), (A).end()
#define ALLR(A) (A).rbegin(), (A).rend()

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long long lf;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<bool> vb;
typedef vector<lf> vd;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<pii> vpii;

const int MAXN = int(1e5) + 10;
const int MAXE = 2 * MAXN;
const int MOD = int(360);
const int oo = INT_MAX;

enum { OPEN, LINE, CLOSE };

struct pt {
  lf x, y;
  pt() {}
  pt(lf x, lf y) : x(x), y(y) {}
};

inline lf x(pt P) { return P.x; }
inline lf y(pt P) { return P.y; }

istream &operator>>(istream &in, pt &p) {
  lf x, y;
  in >> x >> y;
  p = pt(x, y);
  return in;
}

ostream &operator<<(ostream &out, const pt &p) {
  out << double(p.x) << " " << double(p.y);
  return out;
}

pt operator+(const pt &A, const pt &B) { return pt(x(A) + x(B), y(A) + y(B)); }

pt operator-(const pt &A, const pt &B) { return pt(x(A) - x(B), y(A) - y(B)); }

struct Event {
  int t;
  pt p, q;
  Event() {}
  Event(int t, pt p, pt q) : t(t), p(p), q(q) {}
};

bool cmp_Event(const Event &A, const Event &B) {
  if (A.p.x != B.p.x)
    return A.p.x < B.p.x;
  return A.t < B.t;
}

int n;
pt P[2][MAXN];
ll zip[2][2 * MAXN];
int bit[MAXN];
Event events[MAXE];

void add(int i) {
  for (; i < MAXN; i += (i & -i)) {
    ++bit[i];
  }
}

void erase(int i) {
  for (; i < MAXN; i += (i & -i)) {
    --bit[i];
  }
}

int query(int i) {
  int sum = 0;
  for (; i > 0; i -= (i & -i)) {
    sum += bit[i];
  }
  return sum;
}

int main() {

#ifdef LOCAL
  freopen("input", "r", stdin);
  // freopen( "output", "w", stdout );
#else
  // freopen( "input", "r", stdin );
  // freopen( "output", "w", stdout );
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#endif

  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> P[0][i] >> P[1][i];
    if (P[0][i].y > P[1][i].y)
      swap(P[0][i], P[1][i]);
    if (P[0][i].x > P[1][i].x)
      swap(P[0][i], P[1][i]);

    zip[0][i] = P[0][i].x;
    zip[0][i + n] = P[1][i].x;
    zip[1][i] = P[0][i].y;
    zip[1][i + n] = P[1][i].y;
  }
  sort(zip[0], zip[0] + 2 * n);
  sort(zip[1], zip[1] + 2 * n);
  int sz1 = distance(zip[0], unique(zip[0], zip[0] + 2 * n));
  int sz2 = distance(zip[1], unique(zip[1], zip[1] + 2 * n));

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < n; ++j) {
      P[i][j].x = lower_bound(zip[0], zip[0] + sz1, P[i][j].x) - zip[0];
      P[i][j].y = lower_bound(zip[1], zip[1] + sz2, P[i][j].y) - zip[1];
    }
  }
  int t = 0;
  for (int i = 0; i < n; ++i) {
    if (P[0][i].x == P[1][i].x) {
      events[t++] = Event(LINE, P[0][i], P[1][i]);
    } else {
      events[t++] = Event(OPEN, P[0][i], P[0][i]);
      events[t++] = Event(CLOSE, P[1][i], P[1][i]);
    }
  }
  int ans = 0;
  sort(events, events + t, cmp_Event);
  for (int i = 0; i < t; ++i) {
    Event &e = events[i];
    if (e.t == OPEN) {
      add(e.p.y);
    } else if (e.t == CLOSE) {
      erase(e.p.y);
    } else if (e.t == LINE) {
      ans += query(e.q.y) - query(e.p.y - 1);
    }
  }
  cout << ans << '\\n';
  return 0;
}