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

線分配置

Ａ大学は今年もプログラミングコンテストを開催する。作題チームの一員であるあなたは、計算幾何学の問題の入力データの作成を担当することになった。あなたが作りたい入力データは、x 軸または y 軸に平行で、互いに触れ合うことのない線分の集合である。あなたは、次のアルゴリズムに基づいたデータ生成プログラムを開発して、入力データを生成する。

xy 平面上の線分の集合 T を空にする。

次の処理を N 回繰り返す。

x 軸または y 軸に平行な適当な線分 s を作る。

s が T 内のどの線分にも触れない場合は s を T に追加し、触れる場合は s を追加しない。

x 軸または y 軸に平行な N 本の線分を順番に入力し、各線分が平面上に追加されるかどうかを判定するプログラムを作成せよ。

Input

入力は以下の形式で与えられる。

N
px1 py1 qx1 qy1
px2 py2 qx2 qy2
:
pxN pyN qxN qyN

１行目に線分の数 N (1 ≤ N ≤ 100000) が与えられる。続く N 行に、i 番目に追加したい線分の情報が与えられる。各行に与えられる４つの整数 pxi, pyi, qxi, qyi (0 ≤ pxi, pyi, qxi, qyi ≤ 109) は、それぞれ i 番目の線分の端点の x 座標、y 座標、もう一つの端点の x 座標、y 座標を表す。ただし、線分の長さは１以上である。

Output

各線分について、追加される場合「1」を、追加されない場合「0」を１行に出力する。

Sample Input 1

9
0 2 5 2
1 3 1 7
0 6 3 6
2 4 8 4
4 0 4 5
6 3 6 0
5 6 7 6
8 3 8 7
6 5 11 5

Sample Output 1

1
1
0
1
0
1
1
0
1

Solution in C++14 (judge verdict: Memory Limit Exceeded)

#include <bits/stdc++.h>
using namespace std;

using ll = int;

template <typename T>
class node {
public:
	node<T> *l, *r;
	T val, add;
	node(T val_ = 0, node<T>* l_ = nullptr, node<T>* r_ = nullptr) :
		l(l_), r(r_), val(val_), add(0) {}
};

node<int> pool1[100000000];
int it1;

template <typename T>
class DynamicLazySegmentTree {
	const ll n;
	node<T> *root;
	ll size(ll n) {
		ll res = 1;
		while (res < n) res <<= 1ll;
		return res;
	}
	T sub(ll l, ll r, node<T>* n, ll lb, ll ub) {
		if (ub <= l || r <= lb) return 0;
		if (l <= lb && ub <= r) return n->val + n->add * (ub - lb);
		return n->add * (min(r, ub) - max(l, lb)) + (n->l != nullptr ? sub(l, r, n->l, lb, (lb + ub) / 2) : 0) + (n->r != nullptr ? sub(l, r, n->r, (lb + ub) / 2, ub) : 0);
	}
	void suc(ll l, ll r, node<T>* n, ll lb, ll ub, T val) {
		if (ub <= l || r <= lb) return;
		if (l <= lb && ub <= r) {
			n->add += val;
			return;
		}
		n->val += val * (min(r, ub) - max(l, lb));
		if (n->l == nullptr) {
			n->l = &pool1[it1++];
		}
		if (n->r == nullptr) {
			n->r = &pool1[it1++];
		}
		suc(l, r, n->l, lb, (lb + ub) / 2, val);
		suc(l, r, n->r, (lb + ub) / 2, ub, val);
	}
public:
	DynamicLazySegmentTree(ll n_) :
		n(size(n_)) {
		root = &pool1[it1++];
	}
	void add(ll l, ll r, T val) {
		suc(l, r + 1, root, 0, n, val);
	}
	T getSum(ll l, ll r) {
		return sub(l, r + 1, root, 0, n);
	}
};

template <typename T>
class node2 {
public:
	node2<T> *l, *r;
	DynamicLazySegmentTree<T> val, add;
	node2(ll w, node2<T>* l_ = nullptr, node2<T>* r_ = nullptr) : l(l_), r(r_), val(w), add(w) {}
};

template <typename T>
class DynamicLazySegmentTree2 {
	const ll h, w;
	node2<T> *root;
	ll size(ll n) {
		ll res = 1;
		while (res < n) res <<= 1ll;
		return res;
	}
	T sub(ll li, ll lj, ll ri, ll rj, node2<T>* n, ll lb, ll ub) {
		if (ub <= li || ri <= lb) return 0;
		if (li <= lb && ub <= ri) return n->val.getSum(lj, rj - 1) + n->add.getSum(lj, rj - 1) * (ub - lb);
		return n->add.getSum(lj, rj - 1) * (min(ri, ub) - max(li, lb)) + (n->l == nullptr ? 0 : sub(li, lj, ri, rj, n->l, lb, (lb + ub) / 2)) + (n->r == nullptr ? 0 : sub(li, lj, ri, rj, n->r, (lb + ub) / 2, ub));
	}
	void suc(ll li, ll lj, ll ri, ll rj, node2<T>* n, ll lb, ll ub, T val) {
		if (ub <= li || ri <= lb) return;
		if (li <= lb && ub <= ri) {
			n->add.add(lj, rj - 1, val);
			return;
		}
		n->val.add(lj, rj - 1, val * (min(ri, ub) - max(li, lb)));
		if (n->l == nullptr) {
			n->l = new node2<T>(w);
		}
		if (n->r == nullptr) {
			n->r = new node2<T>(w);
		}
		suc(li, lj, ri, rj, n->l, lb, (lb + ub) / 2, val);
		suc(li, lj, ri, rj, n->r, (lb + ub) / 2, ub, val);
	}
public:
	DynamicLazySegmentTree2(ll h_, ll w_) :
		h(size(h_)), w(size(w_)) { root = new node2<T>(w); }
	void add(ll li, ll lj, ll ri, ll rj, T val) {
		suc(li, lj, ri + 1, rj + 1, root, 0, h, val);
	}
	T getSum(ll li, ll lj, ll ri, ll rj) {
		return sub(li, lj, ri + 1, rj + 1, root, 0, h);
	}
};

int main()
{
	cin.sync_with_stdio(false);
	int N;
	cin >> N;
	vector<int> px(N), py(N), qx(N), qy(N), xs, ys;
	for (int i = 0; i < N; i++) {
		cin >> px[i] >> py[i] >> qx[i] >> qy[i];
		xs.push_back(px[i]);
		xs.push_back(qx[i]);
		ys.push_back(py[i]);
		ys.push_back(qy[i]);
	}
	sort(xs.begin(), xs.end());
	sort(ys.begin(), ys.end());
	xs.erase(unique(xs.begin(), xs.end()), xs.end());
	ys.erase(unique(ys.begin(), ys.end()), ys.end());
	for (int i = 0; i < N; i++) {
		px[i] = lower_bound(xs.begin(), xs.end(), px[i]) - xs.begin();
		py[i] = lower_bound(ys.begin(), ys.end(), py[i]) - ys.begin();
		qx[i] = lower_bound(xs.begin(), xs.end(), qx[i]) - xs.begin();
		qy[i] = lower_bound(ys.begin(), ys.end(), qy[i]) - ys.begin();
	}
	DynamicLazySegmentTree2<int> dlst(xs.size(), ys.size());
	for (int i = 0; i < N; i++) {
		int li = min(px[i], qx[i]), lj = min(py[i], qy[i]), ri = max(px[i], qx[i]), rj = max(py[i], qy[i]);
		if (dlst.getSum(li, lj, ri, rj) == 0) {
			puts("1");
			dlst.add(li, lj, ri, rj, 1);
		}
		else {
			puts("0");
		}
	}
	return 0;
}