Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Segment Intersections: Manhattan Geometry

For given $n$ segments which are parallel to X-axis or Y-axis, find the number of intersections of them.

Input

In the first line, the number of segments $n$ is given. In the following $n$ lines, the $i$-th segment is given by coordinates of its end points in the following format:

$x_1 \; y_1 \; x_2 \; y_2$

The coordinates are given in integers.

Output

Print the number of intersections in a line.

Constraints

$1 \leq n \leq 100,000$

$ -1,000,000,000 \leq x_1, y_1, x_2, y_2 \leq 1,000,000,000$

Two parallel segments never overlap or touch.

The number of intersections $\leq 1,000,000$

Sample Input 1

6
2 2 2 5
1 3 5 3
4 1 4 4
5 2 7 2
6 1 6 3
6 5 6 7

Sample Output 1

3

Solution in C++ (judge verdict: Accepted)

#include <cstdio>           // printf(), scanf()
#include <set>
#include <iterator>         // distance()
#include <algorithm>        // swap(), sort(), lower_bound(), upper_bound()

using namespace std;
static const int MAX_N = 100000;
enum { BOTTOM = 0, LEFT, RIGHT, TOP };

struct Point
{
	int x;
	int y;
};

struct Segment
{
	Point p1, p2;
};

class EndPoint
{
public:
	Point p;
	int seg; // ??\????????????ID
	int st;  // ??????????¨????

	EndPoint() {}
	EndPoint(Point p, int seg, int st): p(p), seg(seg), st(st) {}
	bool operator < (const EndPoint &ep) const
	{
		// y ??§?¨?????°???????????????´???
		if (p.y != ep.p.y)
			return p.y < ep.p.y;
		else
			return st < ep.st; // y ??????????????´????????????????????????????????????????????????????????????????????????
	}
};

Segment S[MAX_N];
EndPoint EP[2 * MAX_N]; // ??????????????????
int n;

// ??????????????????: ????????????????????????
int
manhattanIntersection()
{
	int k = 0;
	for (int i = 0; i < n; ++i)
	{
		// ?????? p1,p2 ??????????????????????????¶??????????????´
		if (S[i].p1.y == S[i].p2.y)
		{
			if (S[i].p1.x > S[i].p2.x)
				swap(S[i].p1, S[i].p2);
		}

		else if (S[i].p1.y > S[i].p2.y)
			swap(S[i].p1, S[i].p2);

		if (S[i].p1.y == S[i].p2.y) // ?°´????????????????????????????????????
			EP[k++] = EndPoint(S[i].p1, i, LEFT);

		else // ?????´?????????????????????????????????
		{
			EP[k++] = EndPoint(S[i].p1, i, BOTTOM);
			EP[k++] = EndPoint(S[i].p2, i, TOP);
		}
	}

	sort(EP, EP + k); // ????????? y ??§?¨??????¢?????????????????´???

	set<int> BT; // ????????¢?????¨
	BT.insert(1000000001); // ??????????¨????

	int cnt = 0;
	for (int i = 0; i < k; ++i)
	{
		if (EP[i].st == TOP)
			BT.erase(EP[i].p.x); // ??????????????????
		else if (EP[i].st == BOTTOM)
			BT.insert(EP[i].p.x); // ??????????????????
		else if (EP[i].st == LEFT)
		{
			set<int>::iterator b = BT.lower_bound(S[EP[i].seg].p1.x); // O(log n)
			set<int>::iterator e = BT.upper_bound(S[EP[i].seg].p2.x); // O(log n)
			cnt += distance(b, e); // b ??¨ e ????????¢(????????°)????????????O(k)
		}
	}

	return cnt;
}

int
main(int argc, char** argv)
{
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
		scanf("%d %d %d %d", &S[i].p1.x, &S[i].p1.y, &S[i].p2.x, &S[i].p2.y);

	printf("%d\n", manhattanIntersection());
	return 0;
}