Problem:
線分配置
Ａ大学は今年もプログラミングコンテストを開催する。作題チームの一員であるあなたは、計算幾何学の問題の入力データの作成を担当することになった。あなたが作りたい入力データは、
x
軸または
y
軸に平行で、互いに触れ合うことのない線分の集合である。あなたは、次のアルゴリズムに基づいたデータ生成プログラムを開発して、入力データを生成する。
xy
平面上の線分の集合
T
を空にする。
次の処理を
N
回繰り返す。
x
軸または
y
軸に平行な適当な線分
s
を作る。
s
が
T
内のどの線分にも触れない場合は
s
を
T
に追加し、触れる場合は
s
を追加しない。
x
軸または
y
軸に平行な
N
本の線分を順番に入力し、各線分が平面上に追加されるかどうかを判定するプログラムを作成せよ。
Input
入力は以下の形式で与えられる。
N
px
1
py
1
qx
1
qy
1
px
2
py
2
qx
2
qy
2
:
px
N
py
N
qx
N
qy
N
１行目に線分の数
N
(1 ≤
N
≤ 100000) が与えられる。続く
N
行に、
i
番目に追加したい線分の情報が与えられる。各行に与えられる４つの整数
px
i
,
py
i
,
qx
i
,
qy
i
(0 ≤
px
i
,
py
i
,
qx
i
,
qy
i
≤ 10
9
) は、それぞれ
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

Submitted solutions:

code_snippet: // AOJ #333
// Line Segment Arrangement 2025.2.8

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

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
    pc('0'+n), pc('\n');
}

struct BIT1D {
    int n;
    vector<int> tree;
    BIT1D() : n(0) {}
    BIT1D(int n) : n(n) { tree.assign(n+1, 0); }
    void init(int n_) {
        n = n_;
        tree.assign(n+1, 0);
    }
    void update(int i, int delta) {
        for(; i <= n; i += i & -i)
            tree[i] += delta;
    }
    int query(int i) {
        int s = 0;
        for(; i > 0; i -= i & -i)
            s += tree[i];
        return s;
    }
};
 
struct DS_V {
    vector<int> xs;
    int m;
    vector<vector<int>> ys;
    vector<BIT1D> bit;
 
    DS_V() : m(0) {}
    void init(const vector<pair<int,int>> &updates) {
        vector<int> temp;
        for(auto &p : updates)
            temp.push_back(p.first);
        sort(temp.begin(), temp.end());
        temp.erase(unique(temp.begin(), temp.end()), temp.end());
        xs = temp;
        m = xs.size();
 
        ys.assign(m+1, vector<int>());
        bit.resize(m+1);
 
        for(auto &p : updates){
            int x = p.first, y = p.second;
            int pos = int(lower_bound(xs.begin(), xs.end(), x) - xs.begin()) + 1;
            for(int j = pos; j <= m; j += j & -j)
                ys[j].push_back(y);
        }
        for (int j = 1; j <= m; j++){
            sort(ys[j].begin(), ys[j].end());
            ys[j].erase(unique(ys[j].begin(), ys[j].end()), ys[j].end());
            bit[j].init(ys[j].size());
        }
    }
    void update(int x, int y, int delta) {
        if(m == 0) return;
        int pos = int(lower_bound(xs.begin(), xs.end(), x) - xs.begin()) + 1;
        for(int j = pos; j <= m; j += j & -j) {
            int posY = int(lower_bound(ys[j].begin(), ys[j].end(), y) - ys[j].begin()) + 1;
            bit[j].update(posY, delta);
        }
    }
    int query_internal(int pos, int y) {
        int res = 0;
        for(; pos > 0; pos -= pos & -pos) {
            int posY = int(upper_bound(ys[pos].begin(), ys[pos].end(), y) - ys[pos].begin());
            res += bit[pos].query(posY);
        }
        return res;
    }
    int query_range(int L, int R, int y) {
        if(m == 0) return 0;
        int rpos = int(upper_bound(xs.begin(), xs.end(), R) - xs.begin());
        int lpos = int(lower_bound(xs.begin(), xs.end(), L) - xs.begin()) + 1;
        if(rpos == 0 || lpos > m || lpos > rpos) return 0;
        return query_internal(rpos, y) - query_internal(lpos - 1, y);
    }
};

struct DS_H {
    vector<int> ys;
    int m;
    vector<vector<int>> xs;
    vector<BIT1D> bit;
 
    DS_H() : m(0) {}
    void init(const vector<pair<int,int>> &updates) {
        vector<int> temp;
        for(auto &p : updates)
            temp.push_back(p.first);
        sort(temp.begin(), temp.end());
        temp.erase(unique(temp.begin(), temp.end()), temp.end());
        ys = temp;
        m = ys.size();
 
        xs.assign(m+1, vector<int>());
        bit.resize(m+1);
 
        for(auto &p : updates){
            int y = p.first, x = p.second;
            int pos = int(lower_bound(ys.begin(), ys.end(), y) - ys.begin()) + 1;
            for(int j = pos; j <= m; j += j & -j)
                xs[j].push_back(x);
        }
        for(int j = 1; j <= m; j++){
            sort(xs[j].begin(), xs[j].end());
            xs[j].erase(unique(xs[j].begin(), xs[j].end()), xs[j].end());
            bit[j].init(xs[j].size());
        }
    }
    void update(int y, int x, int delta) {
        if(m == 0) return;
        int pos = int(lower_bound(ys.begin(), ys.end(), y) - ys.begin()) + 1;
        for(int j = pos; j <= m; j += j & -j){
            int posX = int(lower_bound(xs[j].begin(), xs[j].end(), x) - xs[j].begin()) + 1;
            bit[j].update(posX, delta);
        }
    }
    int query_internal(int pos, int x) {
        int res = 0;
        for(; pos > 0; pos -= pos & -pos) {
            int posX = int(upper_bound(xs[pos].begin(), xs[pos].end(), x) - xs[pos].begin());
            res += bit[pos].query(posX);
        }
        return res;
    }
    int query_range(int L, int R, int x) {
        if(m == 0) return 0;
        int rpos = int(upper_bound(ys.begin(), ys.end(), R) - ys.begin());
        int lpos = int(lower_bound(ys.begin(), ys.end(), L) - ys.begin()) + 1;
        if(rpos == 0 || lpos > m || lpos > rpos) return 0;
        return query_internal(rpos, x) - query_internal(lpos - 1, x);
    }
};
 
struct Segment {
    bool vertical;
    int x1, x2, y1, y2;
};
 
int main(){
    int N = Cin();
    vector<Segment> segs(N);
    vector<pair<int,int>> ds_v_updates;
    vector<pair<int,int>> ds_h_updates;
 
    for (int i = 0; i < N; i++){
        int px = Cin(), py = Cin(), qx = Cin(), qy = Cin();
        if(py == qy) {
            int y = py;
            int L = min(px, qx), R = max(px, qx);
            segs[i] = {false, L, R, y, y};
            ds_h_updates.push_back({y, L});
            ds_h_updates.push_back({y, R+1});
        } else {
            int x = px;
            int L = min(py, qy), R = max(py, qy);
            segs[i] = {true, x, x, L, R};
            ds_v_updates.push_back({x, L});
            ds_v_updates.push_back({x, R+1});
        }
    }
 
    DS_V ds_v;
    ds_v.init(ds_v_updates);
    DS_H ds_h;
    ds_h.init(ds_h_updates);
 
    map<int, set<pair<int,int>>> horizontals;
    map<int, set<pair<int,int>>> verticals;
 
    for (int i = 0; i < N; i++){
        if(!segs[i].vertical) {
            int y = segs[i].y1;
            int L = segs[i].x1, R = segs[i].x2;
            bool conflict = false;
            if(horizontals.count(y)){
                auto &st = horizontals[y];
                auto it = st.lower_bound({L, -1});
                if(it != st.end()){
                    if(it->first <= R) conflict = true;
                }
                if(!conflict && it != st.begin()){
                    auto prev_it = it;
                    prev_it--;
                    if(prev_it->second >= L) conflict = true;
                }
            }
            if(!conflict){
                int cnt = ds_v.query_range(L, R, y);
                if(cnt > 0) conflict = true;
            }
 
            if(conflict) Cout(0);
            else {
                Cout(1);
                horizontals[y].insert({L, R});
                ds_h.update(y, L, 1);
                ds_h.update(y, R+1, -1);
            }
        } else {
            int x = segs[i].x1;
            int L = segs[i].y1, R = segs[i].y2;
            bool conflict = false;
            if(verticals.count(x)){
                auto &st = verticals[x];
                auto it = st.lower_bound({L, -1});
                if(it != st.end()){
                    if(it->first <= R) conflict = true;
                }
                if(!conflict && it != st.begin()){
                    auto prev_it = it;
                    prev_it--;
                    if(prev_it->second >= L) conflict = true;
                }
            }
            if(!conflict){
                int cnt = ds_h.query_range(L, R, x);
                if(cnt > 0) conflict = true;
            }
 
            if(conflict) Cout(0);
            else {
                Cout(1);
                verticals[x].insert({L, R});
                ds_v.update(x, L, 1);
                ds_v.update(x, R+1, -1);
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 43452
final_rank: 2

code_snippet: #include <iostream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

// メモリ足りるかな…
// =============================================================== Segtree Part1 ===============================================================
class RangeMax {
public:
	int size_ = 1;
	vector<int> dat;
	
	void init(int sz) {
		size_ = 1;
		while (size_ <= sz) size_ *= 2;
		dat.resize(size_ * 2, -1);
	}

	void update(int pos, int x) {
		pos += size_;
		dat[pos] = max(dat[pos], x);
		while (pos >= 2) {
			pos >>= 1;
			dat[pos] = max(dat[pos * 2 + 0], dat[pos * 2 + 1]);
		}
	}

	int query_(int l, int r, int a, int b, int u) {
		if (l <= a && b <= r) return dat[u];
		if (r <= a || b <= l) return -1;
		int v1 = query_(l, r, a, (a + b) / 2, u * 2);
		int v2 = query_(l, r, (a + b) / 2, b, u * 2 + 1);
		return max(v1, v2);
	}

	int query(int l, int r) {
		return query_(l, r, 0, size_, 1);
	}
};

// =============================================================== Segtree Part2 ===============================================================
class SegmentTree {
public:
	int size_ = 1;
	vector<vector<int>> place;
	vector<RangeMax> dat;

	void init(int sz) {
		size_ = 1;
		while (size_ <= sz) size_ *= 2;
		place.resize(size_ * 2, vector<int>{});
		dat.resize(size_ * 2);
	}

	void initial_add(int pos, int x) {
		pos += size_;
		while (pos >= 1) {
			place[pos].push_back(x);
			pos >>= 1;
		}
	}

	void preparation() {
		for (int i = 1; i < size_ * 2; i++) {
			sort(place[i].begin(), place[i].end());
			place[i].erase(unique(place[i].begin(), place[i].end()), place[i].end());
			dat[i].init(place[i].size() + 2);
		}
	}

	void add(int pos, int l, int r) {
		pos += size_;
		while (pos >= 1) {
			int pos1 = lower_bound(place[pos].begin(), place[pos].end(), l) - place[pos].begin();
			dat[pos].update(pos1, r);
			pos >>= 1;
		}
	}

	int query_(int l, int r, int max_req, int a, int b, int u) {
		if (l <= a && b <= r) {
			int pos1 = lower_bound(place[u].begin(), place[u].end(), max_req + 1) - place[u].begin();
			return dat[u].query(0, pos1);
		}
		if (r <= a || b <= l) return -1;
		int v1 = query_(l, r, max_req, a, (a + b) / 2, u * 2);
		int v2 = query_(l, r, max_req, (a + b) / 2, b, u * 2 + 1);
		return max(v1, v2);
	}

	int query(int l, int r, int max_req) {
		return query_(l, r, max_req, 0, size_, 1);
	}
};

// =============================================================== Main Part ===============================================================
int N;
int px[100009], py[100009], qx[100009], qy[100009];
int T[100009];
int X[100009];
int L[100009];
int R[100009];
set<pair<int, int>> S1[200009];
set<pair<int, int>> S2[200009];
SegmentTree Z1;
SegmentTree Z2;

bool Simulate(int t, int x, int l, int r) {
	// First Check (Same Direction)
	if (t == 1) {
		auto itr = S1[x].lower_bound(make_pair(r + 1, -1));
		if (itr != S1[x].begin()) {
			itr--;
			pair<int, int> rec = (*itr);
			if (rec.second >= l) return false;
		}
	}
	if (t == 2) {
		auto itr = S2[x].lower_bound(make_pair(r + 1, -1));
		if (itr != S2[x].begin()) {
			itr--;
			pair<int, int> rec = (*itr);
			if (rec.second >= l) return false;
		}
	}

	// Second Check (Different Direction)
	if (t == 1) {
		int ret = Z2.query(l, r + 1, x);
		if (ret >= x) return false;
	}
	if (t == 2) {
		int ret = Z1.query(l, r + 1, x);
		if (ret >= x) return false;
	}
	return true;
}

int main() {
	// Step 1. Input
	cin >> N;
	for (int i = 1; i <= N; i++) cin >> px[i] >> py[i] >> qx[i] >> qy[i];

	// Step 2. Compression
	vector<int> ListX;
	vector<int> ListY;
	for (int i = 1; i <= N; i++) ListX.push_back(px[i]);
	for (int i = 1; i <= N; i++) ListX.push_back(qx[i]);
	for (int i = 1; i <= N; i++) ListY.push_back(py[i]);
	for (int i = 1; i <= N; i++) ListY.push_back(qy[i]);
	sort(ListX.begin(), ListX.end()); ListX.erase(unique(ListX.begin(), ListX.end()), ListX.end());
	sort(ListY.begin(), ListY.end()); ListY.erase(unique(ListY.begin(), ListY.end()), ListY.end());
	for (int i = 1; i <= N; i++) px[i] = lower_bound(ListX.begin(), ListX.end(), px[i]) - ListX.begin();
	for (int i = 1; i <= N; i++) qx[i] = lower_bound(ListX.begin(), ListX.end(), qx[i]) - ListX.begin();
	for (int i = 1; i <= N; i++) py[i] = lower_bound(ListY.begin(), ListY.end(), py[i]) - ListY.begin();
	for (int i = 1; i <= N; i++) qy[i] = lower_bound(ListY.begin(), ListY.end(), qy[i]) - ListY.begin();

	// Step 3. Formatting
	for (int i = 1; i <= N; i++) {
		if (px[i] == qx[i]) { T[i] = 1; X[i] = px[i]; L[i] = py[i]; R[i] = qy[i]; }
		if (py[i] == qy[i]) { T[i] = 2; X[i] = py[i]; L[i] = px[i]; R[i] = qx[i]; }
		if (L[i] > R[i]) swap(L[i], R[i]);
	}

	// Step 4. Init Segtree
	Z1.init(ListX.size() + 2);
	Z2.init(ListY.size() + 2);
	for (int i = 1; i <= N; i++) {
		if (T[i] == 1) Z1.initial_add(X[i], L[i]);
		if (T[i] == 2) Z2.initial_add(X[i], L[i]);
	}
	Z1.preparation();
	Z2.preparation();

	// Step 4. Simulation
	for (int i = 1; i <= N; i++) {
		bool ret = Simulate(T[i], X[i], L[i], R[i]);
		if (ret == true) {
			cout << "1" << endl;
			if (T[i] == 1) S1[X[i]].insert(make_pair(L[i], R[i]));
			if (T[i] == 2) S2[X[i]].insert(make_pair(L[i], R[i]));
			if (T[i] == 1) Z1.add(X[i], L[i], R[i]);
			if (T[i] == 2) Z2.add(X[i], L[i], R[i]);
		}
		else {
			cout << "0" << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 640
memory_kb: 174340
final_rank: 8

code_snippet: #include"bits/stdc++.h"
#include<random>
using namespace std;
typedef long long int llint;
typedef pair<int, int> pint;
typedef pair<llint, llint> pllint;
typedef vector<int> vint;
typedef vector<llint> vllint;
typedef vector<pint> vpint;
typedef vector<string> vstring;
typedef vector<pair<llint, llint>> vpllint;
typedef vector<vector<int>> vvint;
typedef vector<vector<llint>> vvllint;
typedef vector<vector<pint>> vvpint;
typedef vector<bool> vbool;
typedef vector<vbool> vvbool;
typedef vector<vpllint> vvpllint;
#define rep(i,n) for(int i=0;i<n;i++)
#define drep(i,n) for(int i=n-1;0<=i;i--)
#define yes(ans) if(ans)cout<<"yes"<<endl;else cout<<"no"<<endl;
#define Yes(ans) if(ans)cout<<"Yes"<<endl;else cout<<"No"<<endl;
#define YES(ans) if(ans)cout<<"YES"<<endl;else cout<<"NO"<<endl;
#define POSSIBLE(ans) if(ans)cout<<"POSSIBLE"<<endl;else cout<<"IMPOSSIBLE"<<endl;
#define Pi 3.1415926535897932384626
#define mod llint(1e9+7)
#define mod9 998244353
#define Inf 2147483647
#define llInf 9223372036854775807
#define all(x) x.begin(),x.end()
#define isin(i,n) (0<=i&&i<n)

struct SegTree {
	//二分木を配列で表したもの
	vector<set<int>>seg;
	//木の半分の大きさ
	int siz;
	
	//大きさnでsegtreeを初期化する
	SegTree(int n) {
		siz = 1;
		while (siz < n)siz <<= 1;
		seg.resize(siz * 2 - 1);
		siz--;
	}

	set<int> operator[](const int i) {
		return seg[i + siz];
	}

	//区間[a,b)にxをinsertする
	void insert(int a, int b, int x) {
		for (a += siz, b += siz; a < b; a >>= 1, b >>= 1) {
			if (!(a & 1))seg[a++].insert(x);
			if (!(b & 1))seg[--b].insert(x);
		}
		return;
	}

	//aの位置に[l,r]に含まれる数が存在するか
	bool check(int a, pint lr) {
		bool ans = false;
		for (a += siz; 0 <= a; (++a >>= 1)--) {
			if (seg[a].lower_bound(lr.first) != seg[a].upper_bound(lr.second))ans = true;
		}
		return ans;
	}

	void print(int a) {
		for (a += siz; 0 <= a; (++a >>= 1)--) {
			for (auto j : seg[a])cout << j << " ";
			if (a == 0)break;
		}cout << endl;
		return;
	}
};

struct xy {
	int x;
	int y;
};

struct edge {
	xy p;
	xy q;
};

int main() {
	int n;
	cin >> n;
	vector<edge>edges(n);
	for (auto& [p, q] : edges)cin >> p.x >> p.y >> q.x >> q.y;
	{
		set<int> x, y;
		rep(i, n) {
			x.insert(edges[i].p.x); x.insert(edges[i].q.x);
			y.insert(edges[i].p.y); y.insert(edges[i].q.y);
		}
		map<int, int>mx, my;
		int i = 0;
		for (auto xx : x)mx[xx] = i++; i = 0;
		for (auto yy : y)my[yy] = i++; i = 0;
		for (auto& [p, q] : edges) {
			p.x = mx[p.x]; p.y = my[p.y];
			q.x = mx[q.x]; q.y = my[q.y];
			if (p.x > q.x)swap(p.x, q.x);
			if (p.y > q.y)swap(p.y, q.y);
		}
	}
	vbool ans(n);
	vector<vector<edge>>vh(2);
	vector<vector<set<pint>>>lr(2, vector<set<pint>>(2 * n));
	vector<SegTree>Seg(2, SegTree(2 * n));
	rep(i, n) {
		edge e = edges[i];
		xy p = e.p, q = e.q;
		bool isVer = p.x == q.x;
		int idx;
		pint LR;
		if (isVer) {
			idx = p.x;
			LR = { p.y,q.y };
		}
		else {
			idx = p.y;
			LR = { p.x,q.x };
		}
		bool isOK = true;
		{
			auto it = lr[isVer][idx].lower_bound(LR);
			if (!(it == lr[isVer][idx].end() || LR.second < (*it).first) ||
				!(it == lr[isVer][idx].begin() || (*--it).second < LR.first)) isOK = false;
		}
		{
			//Segのidxの位置にLRの中に入る奴が無いかどうか調べる
			if (Seg[!isVer].check(idx, LR))isOK = false;
		}
		if (isOK) {
			lr[isVer][idx].insert(LR);
			Seg[isVer].insert(LR.first, LR.second + 1, idx);
			ans[i] = true;
		}
	}
	rep(i, n)cout << ans[i] << endl;
	return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 115936
final_rank: 4

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
#line 1 "/home/kotatsugame/library/datastructure/BIT.cpp"
//1-indexed
#line 3 "/home/kotatsugame/library/datastructure/BIT.cpp"
template<typename T>
struct BIT{
	int n;
	vector<T>bit;
	BIT(int n_=0):n(n_),bit(n_+1){}
	T sum(int i)
	{
		T ans=0;
		for(;i>0;i-=i&-i)ans+=bit[i];
		return ans;
	}
	void add(int i,T a)
	{
		if(i==0)return;
		for(;i<=n;i+=i&-i)bit[i]+=a;
	}
	int lower_bound(T k)//k<=sum(ret)
	{
		if(k<=0)return 0;
		int ret=0,i=1;
		while((i<<1)<=n)i<<=1;
		for(;i;i>>=1)
			if(ret+i<=n&&bit[ret+i]<k)k-=bit[ret+=i];
		return ret+1;
	}
};
#line 7 "a.cpp"
int N;
int X1[1<<17],Y1[1<<17],X2[1<<17],Y2[1<<17];
vector<int>xv,yv;
vector<pair<int,int> >xL,xR,yL,yR;
set<pair<int,int> >X[1<<17],Y[1<<17];
bool intersect(pair<int,int>A,pair<int,int>B)
{
	return !(A.second<B.first||B.second<A.first);
}
const int B=300,W=(100000+B-1)/B;
vector<int>xyL[W],xyR[W],yxL[W],yxR[W];
vector<BIT<int> >xLP(W,BIT<int>(B)),xRP(W,BIT<int>(B)),yLP(W,BIT<int>(B)),yRP(W,BIT<int>(B));
vector<pair<int,int> >xyLD[W],xyRD[W],yxLD[W],yxRD[W];
main()
{
	cin>>N;
	for(int i=0;i<N;i++)
	{
		cin>>X1[i]>>Y1[i]>>X2[i]>>Y2[i];
		if(X1[i]==X2[i])
		{
			xv.push_back(X1[i]);
			if(Y1[i]>Y2[i])swap(Y1[i],Y2[i]);
			xL.push_back(make_pair(X1[i],Y1[i]));
			xR.push_back(make_pair(X1[i],Y2[i]));
		}
		else
		{
			yv.push_back(Y1[i]);
			if(X1[i]>X2[i])swap(X1[i],X2[i]);
			yL.push_back(make_pair(Y1[i],X1[i]));
			yR.push_back(make_pair(Y1[i],X2[i]));
		}
	}
	sort(xv.begin(),xv.end());
	sort(yv.begin(),yv.end());
	sort(xL.begin(),xL.end());
	sort(xR.begin(),xR.end());
	sort(yL.begin(),yL.end());
	sort(yR.begin(),yR.end());
	for(int i=0;i<xv.size();i+=B)
	{
		int id=i/B;
		for(int j=0;j<B&&i+j<xv.size();j++)
		{
			xyL[id].push_back(xL[i+j].second);
			xyR[id].push_back(xR[i+j].second);
		}
		sort(xyL[id].begin(),xyL[id].end());
		xyL[id].erase(unique(xyL[id].begin(),xyL[id].end()),xyL[id].end());
		sort(xyR[id].begin(),xyR[id].end());
		xyR[id].erase(unique(xyR[id].begin(),xyR[id].end()),xyR[id].end());
	}
	for(int i=0;i<yv.size();i+=B)
	{
		int id=i/B;
		for(int j=0;j<B&&i+j<yv.size();j++)
		{
			yxL[id].push_back(yL[i+j].second);
			yxR[id].push_back(yR[i+j].second);
		}
		sort(yxL[id].begin(),yxL[id].end());
		yxL[id].erase(unique(yxL[id].begin(),yxL[id].end()),yxL[id].end());
		sort(yxR[id].begin(),yxR[id].end());
		yxR[id].erase(unique(yxR[id].begin(),yxR[id].end()),yxR[id].end());
	}
	for(int i=0;i<N;i++)
	{
		bool now=true;
		if(X1[i]==X2[i])
		{
			int xi=lower_bound(xv.begin(),xv.end(),X1[i])-xv.begin();
			set<pair<int,int> >::iterator it=X[xi].upper_bound(make_pair(Y1[i],-1));
			if(it!=X[xi].end()&&intersect(*it,make_pair(Y1[i],Y2[i])))now=false;
			if(it!=X[xi].begin()&&intersect(*--it,make_pair(Y1[i],Y2[i])))now=false;
			int L=lower_bound(yv.begin(),yv.end(),Y1[i])-yv.begin();
			int R=upper_bound(yv.begin(),yv.end(),Y2[i])-yv.begin();
			int cnt=0,out=0;
			if(L%B!=0)
			{
				int id=L/B;
				for(pair<int,int>p:yxLD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					cnt++;
					if(p.second>X1[i])out++;
				}
				for(pair<int,int>p:yxRD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					if(p.second<X1[i])out++;
				}
				L=(L+B-1)/B*B;
			}
			while(L+B<=R)
			{
				int id=L/B;
				cnt+=yxLD[id].size();
				int jd=upper_bound(yxL[id].begin(),yxL[id].end(),X1[i])-yxL[id].begin();
				out+=yLP[id].sum(yxL[id].size())-yLP[id].sum(jd);
				jd=lower_bound(yxR[id].begin(),yxR[id].end(),X1[i])-yxR[id].begin();
				out+=yRP[id].sum(jd);
				L+=B;
			}
			if(L<R)
			{
				int id=L/B;
				for(pair<int,int>p:yxLD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					cnt++;
					if(p.second>X1[i])out++;
				}
				for(pair<int,int>p:yxRD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					if(p.second<X1[i])out++;
				}
			}
			if(cnt>out)now=false;
		}
		else
		{
			int yi=lower_bound(yv.begin(),yv.end(),Y1[i])-yv.begin();
			set<pair<int,int> >::iterator it=Y[yi].upper_bound(make_pair(X1[i],-1));
			if(it!=Y[yi].end()&&intersect(*it,make_pair(X1[i],X2[i])))now=false;
			if(it!=Y[yi].begin()&&intersect(*--it,make_pair(X1[i],X2[i])))now=false;
			int L=lower_bound(xv.begin(),xv.end(),X1[i])-xv.begin();
			int R=upper_bound(xv.begin(),xv.end(),X2[i])-xv.begin();
			int cnt=0,out=0;
			if(L%B!=0)
			{
				int id=L/B;
				for(pair<int,int>p:xyLD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					cnt++;
					if(p.second>Y1[i])out++;
				}
				for(pair<int,int>p:xyRD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					if(p.second<Y1[i])out++;
				}
				L=(L+B-1)/B*B;
			}
			while(L+B<=R)
			{
				int id=L/B;
				cnt+=xyLD[id].size();
				int jd=upper_bound(xyL[id].begin(),xyL[id].end(),Y1[i])-xyL[id].begin();
				out+=xLP[id].sum(xyL[id].size())-xLP[id].sum(jd);
				jd=lower_bound(xyR[id].begin(),xyR[id].end(),Y1[i])-xyR[id].begin();
				out+=xRP[id].sum(jd);
				L+=B;
			}
			if(L<R)
			{
				int id=L/B;
				for(pair<int,int>p:xyLD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					cnt++;
					if(p.second>Y1[i])out++;
				}
				for(pair<int,int>p:xyRD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					if(p.second<Y1[i])out++;
				}
			}
			if(cnt>out)now=false;
		}
		cout<<now<<endl;
		if(!now)continue;
		if(X1[i]==X2[i])
		{
			int xi=lower_bound(xv.begin(),xv.end(),X1[i])-xv.begin();
			X[xi].insert(make_pair(Y1[i],Y2[i]));
			int Lid=lower_bound(xL.begin(),xL.end(),make_pair(X1[i],Y1[i]))-xL.begin();
			int Rid=lower_bound(xR.begin(),xR.end(),make_pair(X1[i],Y2[i]))-xR.begin();
			xyLD[Lid/B].push_back(make_pair(X1[i],Y1[i]));
			xyRD[Rid/B].push_back(make_pair(X1[i],Y2[i]));
			int jd=lower_bound(xyL[Lid/B].begin(),xyL[Lid/B].end(),Y1[i])-xyL[Lid/B].begin();
			xLP[Lid/B].add(jd+1,1);
			jd=lower_bound(xyR[Rid/B].begin(),xyR[Rid/B].end(),Y2[i])-xyR[Rid/B].begin();
			xRP[Rid/B].add(jd+1,1);
		}
		else
		{
			int yi=lower_bound(yv.begin(),yv.end(),Y1[i])-yv.begin();
			Y[yi].insert(make_pair(X1[i],X2[i]));
			int Lid=lower_bound(yL.begin(),yL.end(),make_pair(Y1[i],X1[i]))-yL.begin();
			int Rid=lower_bound(yR.begin(),yR.end(),make_pair(Y1[i],X2[i]))-yR.begin();
			yxLD[Lid/B].push_back(make_pair(Y1[i],X1[i]));
			yxRD[Rid/B].push_back(make_pair(Y1[i],X2[i]));
			int jd=lower_bound(yxL[Lid/B].begin(),yxL[Lid/B].end(),X1[i])-yxL[Lid/B].begin();
			yLP[Lid/B].add(jd+1,1);
			jd=lower_bound(yxR[Rid/B].begin(),yxR[Rid/B].end(),X2[i])-yxR[Rid/B].begin();
			yRP[Rid/B].add(jd+1,1);
		}
	}
}
accuracy: 1
time_ms: 570
memory_kb: 29244
final_rank: 1

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
#line 1 "/home/kotatsugame/library/datastructure/BIT.cpp"
//1-indexed
#line 3 "/home/kotatsugame/library/datastructure/BIT.cpp"
template<typename T>
struct BIT{
	int n;
	vector<T>bit;
	BIT(int n_=0):n(n_),bit(n_+1){}
	T sum(int i)
	{
		T ans=0;
		for(;i>0;i-=i&-i)ans+=bit[i];
		return ans;
	}
	void add(int i,T a)
	{
		if(i==0)return;
		for(;i<=n;i+=i&-i)bit[i]+=a;
	}
	int lower_bound(T k)//k<=sum(ret)
	{
		if(k<=0)return 0;
		int ret=0,i=1;
		while((i<<1)<=n)i<<=1;
		for(;i;i>>=1)
			if(ret+i<=n&&bit[ret+i]<k)k-=bit[ret+=i];
		return ret+1;
	}
};
#line 7 "a.cpp"
int N;
int X1[1<<17],Y1[1<<17],X2[1<<17],Y2[1<<17];
vector<int>xv,yv;
vector<pair<int,int> >xL,xR,yL,yR;
set<pair<int,int> >X[1<<17],Y[1<<17];
bool intersect(pair<int,int>A,pair<int,int>B)
{
	return !(A.second<B.first||B.second<A.first);
}
const int B=300,W=(100000+B-1)/B;
vector<int>xyL[W],xyR[W],yxL[W],yxR[W];
vector<BIT<int> >xLP(W,B),xRP(W,B),yLP(W,B),yRP(W,B);
vector<pair<int,int> >xyLD[W],xyRD[W],yxLD[W],yxRD[W];
main()
{
	cin>>N;
	for(int i=0;i<N;i++)
	{
		cin>>X1[i]>>Y1[i]>>X2[i]>>Y2[i];
		if(X1[i]==X2[i])
		{
			xv.push_back(X1[i]);
			if(Y1[i]>Y2[i])swap(Y1[i],Y2[i]);
			xL.push_back(make_pair(X1[i],Y1[i]));
			xR.push_back(make_pair(X1[i],Y2[i]));
		}
		else
		{
			yv.push_back(Y1[i]);
			if(X1[i]>X2[i])swap(X1[i],X2[i]);
			yL.push_back(make_pair(Y1[i],X1[i]));
			yR.push_back(make_pair(Y1[i],X2[i]));
		}
	}
	sort(xv.begin(),xv.end());
	xv.erase(unique(xv.begin(),xv.end()),xv.end());
	sort(yv.begin(),yv.end());
	yv.erase(unique(yv.begin(),yv.end()),yv.end());
	sort(xL.begin(),xL.end());
	sort(xR.begin(),xR.end());
	sort(yL.begin(),yL.end());
	sort(yR.begin(),yR.end());
	for(int i=0;i<xL.size();i+=B)
	{
		int id=i/B;
		for(int j=0;j<B&&i+j<xL.size();j++)
		{
			xyL[id].push_back(xL[i+j].second);
			xyR[id].push_back(xR[i+j].second);
		}
		sort(xyL[id].begin(),xyL[id].end());
		xyL[id].erase(unique(xyL[id].begin(),xyL[id].end()),xyL[id].end());
		sort(xyR[id].begin(),xyR[id].end());
		xyR[id].erase(unique(xyR[id].begin(),xyR[id].end()),xyR[id].end());
	}
	for(int i=0;i<yL.size();i+=B)
	{
		int id=i/B;
		for(int j=0;j<B&&i+j<yL.size();j++)
		{
			yxL[id].push_back(yL[i+j].second);
			yxR[id].push_back(yR[i+j].second);
		}
		sort(yxL[id].begin(),yxL[id].end());
		yxL[id].erase(unique(yxL[id].begin(),yxL[id].end()),yxL[id].end());
		sort(yxR[id].begin(),yxR[id].end());
		yxR[id].erase(unique(yxR[id].begin(),yxR[id].end()),yxR[id].end());
	}
	for(int i=0;i<N;i++)
	{
		bool now=true;
		if(X1[i]==X2[i])
		{
			int xi=lower_bound(xv.begin(),xv.end(),X1[i])-xv.begin();
			set<pair<int,int> >::iterator it=X[xi].upper_bound(make_pair(Y1[i],-1));
			if(it!=X[xi].end()&&intersect(*it,make_pair(Y1[i],Y2[i])))now=false;
			if(it!=X[xi].begin()&&intersect(*--it,make_pair(Y1[i],Y2[i])))now=false;
			int L=lower_bound(yv.begin(),yv.end(),Y1[i])-yv.begin();
			int R=upper_bound(yv.begin(),yv.end(),Y2[i])-yv.begin();
			int cnt=0,out=0;
			if(L%B!=0)
			{
				int id=L/B;
				for(pair<int,int>p:yxLD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					cnt++;
					if(p.second>X1[i])out++;
				}
				for(pair<int,int>p:yxRD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					if(p.second<X1[i])out++;
				}
				L=(L+B-1)/B*B;
			}
			while(L+B<=R)
			{
				int id=L/B;
				cnt+=yxLD[id].size();
				int jd=upper_bound(yxL[id].begin(),yxL[id].end(),X1[i])-yxL[id].begin();
				out+=yLP[id].sum(yxL[id].size())-yLP[id].sum(jd);
				jd=lower_bound(yxR[id].begin(),yxR[id].end(),X1[i])-yxR[id].begin();
				out+=yRP[id].sum(jd);
				L+=B;
			}
			if(L<R)
			{
				int id=L/B;
				for(pair<int,int>p:yxLD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					cnt++;
					if(p.second>X1[i])out++;
				}
				for(pair<int,int>p:yxRD[id])if(Y1[i]<=p.first&&p.first<=Y2[i])
				{
					if(p.second<X1[i])out++;
				}
			}
			if(cnt>out)now=false;
		}
		else
		{
			int yi=lower_bound(yv.begin(),yv.end(),Y1[i])-yv.begin();
			set<pair<int,int> >::iterator it=Y[yi].upper_bound(make_pair(X1[i],-1));
			if(it!=Y[yi].end()&&intersect(*it,make_pair(X1[i],X2[i])))now=false;
			if(it!=Y[yi].begin()&&intersect(*--it,make_pair(X1[i],X2[i])))now=false;
			int L=lower_bound(xv.begin(),xv.end(),X1[i])-xv.begin();
			int R=upper_bound(xv.begin(),xv.end(),X2[i])-xv.begin();
			int cnt=0,out=0;
			if(L%B!=0)
			{
				int id=L/B;
				for(pair<int,int>p:xyLD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					cnt++;
					if(p.second>Y1[i])out++;
				}
				for(pair<int,int>p:xyRD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					if(p.second<Y1[i])out++;
				}
				L=(L+B-1)/B*B;
			}
			while(L+B<=R)
			{
				int id=L/B;
				cnt+=xyLD[id].size();
				int jd=upper_bound(xyL[id].begin(),xyL[id].end(),Y1[i])-xyL[id].begin();
				out+=xLP[id].sum(xyL[id].size())-xLP[id].sum(jd);
				jd=lower_bound(xyR[id].begin(),xyR[id].end(),Y1[i])-xyR[id].begin();
				out+=xRP[id].sum(jd);
				L+=B;
			}
			if(L<R)
			{
				int id=L/B;
				for(pair<int,int>p:xyLD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					cnt++;
					if(p.second>Y1[i])out++;
				}
				for(pair<int,int>p:xyRD[id])if(X1[i]<=p.first&&p.first<=X2[i])
				{
					if(p.second<Y1[i])out++;
				}
			}
			if(cnt>out)now=false;
		}
		cout<<now<<endl;
		if(!now)continue;
		if(X1[i]==X2[i])
		{
			int xi=lower_bound(xv.begin(),xv.end(),X1[i])-xv.begin();
			X[xi].insert(make_pair(Y1[i],Y2[i]));
			int Lid=lower_bound(xL.begin(),xL.end(),make_pair(X1[i],Y1[i]))-xL.begin();
			int Rid=lower_bound(xR.begin(),xR.end(),make_pair(X1[i],Y2[i]))-xR.begin();
			xyLD[Lid/B].push_back(make_pair(X1[i],Y1[i]));
			xyRD[Rid/B].push_back(make_pair(X1[i],Y2[i]));
			int jd=lower_bound(xyL[Lid/B].begin(),xyL[Lid/B].end(),Y1[i])-xyL[Lid/B].begin();
			xLP[Lid/B].add(jd+1,1);
			jd=lower_bound(xyR[Rid/B].begin(),xyR[Rid/B].end(),Y2[i])-xyR[Rid/B].begin();
			xRP[Rid/B].add(jd+1,1);
		}
		else
		{
			int yi=lower_bound(yv.begin(),yv.end(),Y1[i])-yv.begin();
			Y[yi].insert(make_pair(X1[i],X2[i]));
			int Lid=lower_bound(yL.begin(),yL.end(),make_pair(Y1[i],X1[i]))-yL.begin();
			int Rid=lower_bound(yR.begin(),yR.end(),make_pair(Y1[i],X2[i]))-yR.begin();
			yxLD[Lid/B].push_back(make_pair(Y1[i],X1[i]));
			yxRD[Rid/B].push_back(make_pair(Y1[i],X2[i]));
			int jd=lower_bound(yxL[Lid/B].begin(),yxL[Lid/B].end(),X1[i])-yxL[Lid/B].begin();
			yLP[Lid/B].add(jd+1,1);
			jd=lower_bound(yxR[Rid/B].begin(),yxR[Rid/B].end(),X2[i])-yxR[Rid/B].begin();
			yRP[Rid/B].add(jd+1,1);
		}
	}
}
accuracy: 0.3
time_ms: 10
memory_kb: 17248
final_rank: 10

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 800005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right < node_left || left > node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(2*first_N); //★★1つの線分につき2点あるから、2*first_Nで初期化する★★
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,maxi));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}
		//左側チェック
		if(at != SET[type][loc].begin()){

			at--;
			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(mini,maxi));
	}

	return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 181604
final_rank: 7

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 800005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right < node_left || left > node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(2*first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,-1));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->second || mini > at->first){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(maxi,mini));
	}

	return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 181580
final_rank: 6

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right <= node_left || left >= node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,-1));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->second || mini > at->first){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi+1,loc,0,0,N,type);
		SET[type][loc].insert(make_pair(maxi,mini));
	}

	return 0;
}
accuracy: 0.25
time_ms: 20
memory_kb: 97908
final_rank: 12

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right < node_left || left > node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,-1));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi <= at->second || mini >= at->first){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(maxi,mini));
	}

	return 0;
}
accuracy: 0.25
time_ms: 30
memory_kb: 97968
final_rank: 13

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right < node_left || left > node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,0));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->second || mini > at->first){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(maxi,mini));
	}

	return 0;
}
accuracy: 0.25
time_ms: 30
memory_kb: 97988
final_rank: 14

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right < node_left || left > node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,-1));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->second || mini > at->first){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(maxi,mini));
	}

	return 0;
}
accuracy: 0.25
time_ms: 20
memory_kb: 97864
final_rank: 11

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right < node_left || left > node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,maxi));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->second || mini > at->first){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}
		//左側チェック
		if(at != SET[type][loc].begin()){

			at--;

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}
		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(mini,maxi));
	}

	return 0;
}
accuracy: 0.2
time_ms: 20
memory_kb: 96968
final_rank: 15

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right <= node_left || left >= node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,maxi));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}
		//左側チェック
		/*if(at != SET[type][loc].begin()){

			at--;

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}*/
		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		//SET[type][loc].insert(make_pair(mini,maxi));
		SET[type][loc].insert(make_pair(maxi,mini));
	}

	return 0;
}
accuracy: 0.2
time_ms: 20
memory_kb: 96980
final_rank: 18

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right <= node_left || left >= node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,maxi));
		//右側チェック
		if(at != SET[type][loc].end()){

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}
		//左側チェック
		if(at != SET[type][loc].begin()){

			at--;

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}
		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(mini,maxi));
	}

	return 0;
}
accuracy: 0.2
time_ms: 20
memory_kb: 96988
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right <= node_left || left >= node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,-1));
		if(at != SET[type][loc].end()){

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(mini,maxi));
	}

	return 0;
}
accuracy: 0.2
time_ms: 20
memory_kb: 96976
final_rank: 17

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 500005
typedef pair<int,int> P;

enum Type{
	TATE,
	YOKO,
};

struct Line{

	int x1,y1,x2,y2;
};

int N;
vector<int> X,Y;
set<int> table[2][SIZE];
set<P> SET[2][SIZE];
map<int,int> map_X,map_Y;
Type rev[2] = {YOKO,TATE};
Line line[SIZE];

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,int value,int node_id,int node_left,int node_right,Type type){

	if(right <= node_left || left >= node_right)return;
	else if(left <= node_left && right >= node_right){

		table[type][node_id].insert(value);

	}else{
		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2,type);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2,node_right,type);
	}
}

bool isCross(int loc,int mini,int maxi,Type type){

	loc += N-1;

	while(true){

		if(table[type][loc].lower_bound(mini) != table[type][loc].upper_bound(maxi)){

			return true;
		}
		if(loc == 0){

			return false;
		}
		loc = (loc-1)/2;
	}
	return false;
}


int main(){

	int first_N;
	scanf("%d",&first_N);

	for(int i = 0; i < first_N; i++){

		scanf("%d %d %d %d",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);

		X.push_back(line[i].x1);
		X.push_back(line[i].x2);
		Y.push_back(line[i].y1);
		Y.push_back(line[i].y2);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	for(int i = 0; i < X.size(); i++){

		map_X[X[i]] = i;
	}

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());
	for(int i = 0; i < Y.size(); i++){

		map_Y[Y[i]] = i;
	}

	N = 1;
	init(first_N);
	Type type;
	int loc,mini,maxi;

	for(int i = 0; i < first_N; i++){

		if(line[i].x1 == line[i].x2){

			type = TATE;
			loc = map_X[line[i].x1];
			mini = map_Y[min(line[i].y1,line[i].y2)];
			maxi = map_Y[max(line[i].y1,line[i].y2)];

		}else{

			type = YOKO;
			loc = map_Y[line[i].y1];
			mini = map_X[min(line[i].x1,line[i].x2)];
			maxi = map_X[max(line[i].x1,line[i].x2)];
		}

		//垂直交差チェック
		if(isCross(loc,mini,maxi,rev[type])){

			printf("0\n");
			continue;
		}

		//水平交差チェック
		auto at = SET[type][loc].lower_bound(make_pair(mini,maxi));//lower_boundでは要素1のみ見られるっぽい
		if(at != SET[type][loc].end()){

			if(maxi < at->first || mini > at->second){

				//Do nothing
			}else{
				printf("0\n");
				continue;
			}
		}

		printf("1\n");
		add(mini,maxi,loc,0,0,N-1,type);
		SET[type][loc].insert(make_pair(mini,maxi));
	}

	return 0;
}
accuracy: 0.2
time_ms: 20
memory_kb: 96972
final_rank: 16

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;



struct SegmentTree{
    int sz;
    vector<set<int>> seg;
    explicit SegmentTree(int n) {
        sz = 1;
        while(sz < n) sz <<= 1;
        seg.resize(2*sz);
    }

    void update(int k, int a, int b){
        for(a += sz, b += sz; a < b; a >>=1, b>>=1){
            if(a & 1) seg[a++].emplace(k);
            if(b & 1) seg[--b].emplace(k);
        }
    }

    bool query(int x, int a, int b){
        for (x += sz; x; x >>= 1) {
            if(seg[x].lower_bound(a) != seg[x].lower_bound(b)) return false;
        }
        return true;
    }

};
int main() {
    int n;
    cin >> n;
    vector<int> px(n), py(n), qx(n), qy(n);
    vector<int> zx(2*n), zy(2*n);
    for (int i = 0; i < n; ++i) {
        scanf("%d %d %d %d", &px[i], &py[i], &qx[i], &qy[i]);
        zx[i] = px[i]; zx[i+n] = qx[i];
        zy[i] = py[i]; zy[i+n] = qy[i];
    }
    sort(zx.begin(), zx.end());
    zx.erase(unique(zx.begin(), zx.end()), zx.end());
    sort(zy.begin(), zy.end());
    zy.erase(unique(zy.begin(), zy.end()), zy.end());
    auto fx = [&](int x){ return lower_bound(zx.begin(),zx.end(), x) - zx.begin(); };
    auto fy = [&](int y){ return lower_bound(zy.begin(),zy.end(), y) - zy.begin(); };
    SegmentTree segx(zx.size()), segy(zy.size());
    vector<set<int>> sx(zx.size()), sy(zy.size());
    for (int i = 0; i < n; ++i) {
        px[i] = fx(px[i]), py[i] = fy(py[i]);
        qx[i] = fx(qx[i]), qy[i] = fy(qy[i]);
        if(px[i] > qx[i]) swap(px[i], qx[i]);
        if(py[i] > qy[i]) swap(py[i], qy[i]);
        if(px[i] == qx[i]){
            int ok = 1;
            if(!sx[px[i]].empty()){
                auto l = sx[px[i]].lower_bound(py[i]<<1), r = sx[px[i]].lower_bound((qy[i]+1)<<1);
                if(l != r){
                    ok = 0;
                }else if(l != sx[px[i]].end() && (*l&1)){
                    ok = 0;
                }
            }
            if(ok && !segx.query(px[i], py[i], qy[i]+1)){
                ok = 0;
            }
            if(ok){
                sx[px[i]].emplace((py[i]<<1)|0);
                sx[px[i]].emplace((qy[i]<<1)|1);
                segy.update(px[i], py[i], qy[i]+1);
                puts("1");
            }else {
                puts("0");
            }
        }else {
            int ok = 1;
            if(!sy[py[i]].empty()){
                auto l = sy[py[i]].lower_bound(px[i]<<1), r = sy[py[i]].lower_bound((qx[i]+1)<<1);
                if(l != r){
                    ok = 0;
                }else if(l != sy[py[i]].end() && (*l&1)){
                    ok = 0;
                }
            }
            if(ok && !segy.query(py[i], px[i], qx[i]+1)){
                ok = 0;
            }
            if(ok){
                sy[py[i]].emplace((px[i]<<1)|0);
                sy[py[i]].emplace((qx[i]<<1)|1);
                segx.update(py[i], px[i], qx[i]+1);
                puts("1");
            }else puts("0");
        }
    }
    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 85448
final_rank: 3

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;


struct LazySegmentTree{
    int sz, height{};
    vector<set<int>> seg; vector<set<int>> lazy;
    explicit LazySegmentTree(int n) {
        sz = 1; while(sz < n) sz <<= 1, height++;
        seg.resize(2*sz);
        lazy.resize(2*sz);
    }
    bool reflect(int k){
        if(lazy[k].empty()) return false;
        for (auto &&i : lazy[k]) {
            seg[k].emplace(i);
        }
        return true;
    }

    void eval(int k){
        if(lazy[k].empty()) return;
        for (auto &&i : lazy[k]) {
            lazy[(k<<1)|0].emplace(i);
            lazy[(k<<1)|1].emplace(i);
        }
        reflect(k);
        lazy[k].clear();
    }
    void thrust(int k){ for (int i = height; i; --i) eval(k>>i); }
    void recalc(int k) {
        while(k >>= 1) {
            if(reflect((k<<1)|0)){
                for (auto &&i : lazy[(k<<1)|0]) {
                    seg[k].emplace(i);
                }
            }
            if(reflect((k<<1)|1)){
                for (auto &&i : lazy[(k<<1)|1]) {
                    seg[k].emplace(i);
                }
            }
        }
    }
    void update(int a, int b, const int &x){
        thrust(a += sz); thrust(b += sz-1);
        for (int l = a, r = b+1;l < r; l >>=1, r >>= 1) {
            if(l&1) lazy[l].emplace(x), l++;
            if(r&1) --r, lazy[r].emplace(x);
        }
        recalc(a);
        recalc(b);
    }

    bool query(int a, int b, int vl, int vr){ // [l, r)
        thrust(a += sz);
        thrust(b += sz-1);
        for(int l = a, r = b+1; l < r; l >>=1, r>>=1) {
            if (l & 1) {
                reflect(l);
                if(seg[l].lower_bound(vl) != seg[l].lower_bound(vr)) return false;
                l++;
            }
            if (r & 1) {
                --r;
                reflect(r);
                if(seg[r].lower_bound(vl) != seg[r].lower_bound(vr)) return false;
            }
        }
        return true;
    }
};

int main() {
    int n;
    cin >> n;
    vector<int> px(n), py(n), qx(n), qy(n);
    vector<int> zx(2*n), zy(2*n);
    for (int i = 0; i < n; ++i) {
        scanf("%d %d %d %d", &px[i], &py[i], &qx[i], &qy[i]);
        zx[i] = px[i]; zx[i+n] = qx[i];
        zy[i] = py[i]; zy[i+n] = qy[i];
    }
    sort(zx.begin(), zx.end());
    zx.erase(unique(zx.begin(), zx.end()), zx.end());
    sort(zy.begin(), zy.end());
    zy.erase(unique(zy.begin(), zy.end()), zy.end());
    auto fx = [&](int x){ return lower_bound(zx.begin(),zx.end(), x) - zx.begin(); };
    auto fy = [&](int y){ return lower_bound(zy.begin(),zy.end(), y) - zy.begin(); };
    LazySegmentTree segx(zx.size()), segy(zy.size());
    for (int i = 0; i < n; ++i) {
        px[i] = fx(px[i]), py[i] = fy(py[i]);
        qx[i] = fx(qx[i]), qy[i] = fy(qy[i]);
        if(px[i] > qx[i]) swap(px[i], qx[i]);
        if(py[i] > qy[i]) swap(py[i], qy[i]);
        if(segx.query(px[i], qx[i]+1, py[i], qy[i]+1) && segy.query(py[i], qy[i]+1, px[i], qx[i]+1)){
            puts("1");
            if(px[i] == qx[i]) segy.update(py[i], qy[i]+1, px[i]);
            else segx.update(px[i], qx[i]+1, py[i]);
        } else puts("0");
    }
    return 0;
}
accuracy: 0.5
time_ms: 3580
memory_kb: 151736
final_rank: 9

code_snippet: #include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
#include <set>
#include <unordered_map>
#include <utility>
using namespace std;
using ll = int;

set<pair<ll, ll> > x_p[400005];
set<pair<ll, ll> > y_p[400005];
set<ll> x_set[1 << 20];
set<ll> y_set[1 << 20];

void update(int a,int b, int k, int l, int r, int x, int x_tag) {
	if (b <= l || r <= a) return;
	
	if (l <= a && b <= r) {
		if (x_tag) x_set[k].insert(x);
		else y_set[k].insert(x);
		return;
	}
	else {
		update(a, (a + b) / 2, k * 2 + 0, l, r, x, x_tag);
		update((a + b) / 2, b, k * 2 + 1, l, r, x, x_tag);
	}
}

void update(int sx, int tx, int x, int x_tag) {
	update(0, 1 << 19, 1, sx, tx, x, x_tag);
}

bool query(int a, int b, int k, int kx, int s, int t, int x_tag) {
    if (b <= kx || kx < a) return false;
	
	bool f = false;
	if (x_tag) {
		auto itr = x_set[k].lower_bound(s);
		if (itr != x_set[k].end() && *itr <= t) f = true;
	}
	else {
		auto itr = y_set[k].lower_bound(s);
		if (itr != y_set[k].end() && *itr <= t) f = true;
	}

    if (b - a > 1) {
        f |= query(a, (a + b) / 2, k * 2 + 0, kx, s, t, x_tag);
        f |= query((a + b) / 2, b, k * 2 + 1, kx, s, t, x_tag);
    }
	
	return f;
}

bool query(int kx, int s, int t, int x_tag) {
    return query(0, 1 << 19, 1, kx, s, t, x_tag);
}

unordered_map<ll, ll> zip;
ll n;
ll sx[100000];
ll sy[100000];
ll tx[100000];
ll ty[100000];

int main() {
    {
        vector<ll> point;
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> sx[i] >> sy[i] >> tx[i] >> ty[i];
		
            point.push_back(sx[i]);
            point.push_back(sy[i]);
            point.push_back(tx[i]);
            point.push_back(ty[i]);
        }
	
        sort(point.begin(), point.end());
        point.erase(unique(point.begin(), point.end()), point.end());
        for (int i = 0; i < point.size(); i++) {
            zip[point[i]] = i;
        }
    }
	
    for (int i = 0; i < n; i++) {
        ll px, py;
        ll qx, qy;
		
        px = zip[sx[i]];
        py = zip[sy[i]];
        qx = zip[tx[i]];
        qy = zip[ty[i]];
        
        if (px > qx) swap(px, qx);
        if (py > qy) swap(py, qy);
		
        if (py == qy) {
            auto itr1 = x_p[py].lower_bound({px, qx});
            bool f = false;

            if (itr1 != x_p[py].end()) {
                if (itr1->first <= qx) {
                    f |= true;
                }
            }
            if (itr1 != x_p[py].begin()) {
                itr1--;
                if (itr1->second >= px) {
                    f |= true;
                }
            }
            
            if (f ||
                query(py, px, qx, 1)) {
                cout << 0 << '\n';
            }
            else {
                cout << 1 << '\n';
                x_p[py].insert({px, qx});
                update(px, qx + 1, py, 0);
            }
        }
        else {
            auto itr1 = y_p[px].lower_bound({py, qy});
            bool f = false;

            if (itr1 != y_p[px].end()) {
                if (itr1->first <= qy) {
                    f |= true;
                }
            }
            if (itr1 != y_p[px].begin()) {
                itr1--;
                if (itr1->second >= py) {
                    f |= true;
                }
            }
            
            if (f ||
                query(px, py, qy, 0)) {
                cout << 0 << '\n';
            }
            else {
                cout << 1 << '\n';
                y_p[px].insert({py, qy});
                update(py, qy + 1, px, 1);
            }
        }
    }
    
    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 165420
final_rank: 5

code_snippet: #include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
#include <set>
#include <unordered_map>
#include <utility>
using namespace std;
using ll = int;

set<pair<ll, ll> > x_p[400005];
set<pair<ll, ll> > y_p[400005];
set<ll> x_set[1 << 20];
set<ll> y_set[1 << 20];

void update(int a,int b, int k, int l, int r, int x, int x_tag) {
	if (b <= l || r <= a) return;
	
	if (l <= a && b <= r) {
		if (x_tag) x_set[k].insert(x);
		else y_set[k].insert(x);
		return;
	}
	else {
		update(a, (a + b) / 2, k * 2 + 0, l, r, x, x_tag);
		update((a + b) / 2, b, k * 2 + 1, l, r, x, x_tag);
	}
}

void update(int sx, int tx, int x, int x_tag) {
	update(0, 1 << 19, 1, sx, tx, x, x_tag);
}

bool query(int a, int b, int k, int kx, int s, int t, int x_tag) {
    if (b <= kx || kx < a) return false;
	
	bool f = false;
	if (x_tag) {
		auto itr = x_set[k].lower_bound(s);
		if (itr != x_set[k].end() && *itr <= t) f = true;
	}
	else {
		auto itr = y_set[k].lower_bound(s);
		if (itr != y_set[k].end() && *itr <= t) f = true;
	}

    if (b - a > 1) {
        f |= query(a, (a + b) / 2, k * 2 + 0, kx, s, t, x_tag);
        f |= query((a + b) / 2, b, k * 2 + 1, kx, s, t, x_tag);
    }
	
	return f;
}

bool query(int kx, int s, int t, int x_tag) {
    return query(0, 1 << 19, 1, kx, s, t, x_tag);
}

unordered_map<ll, ll> zip;
ll n;
ll sx[100000];
ll sy[100000];
ll tx[100000];
ll ty[100000];

int main() {
    {
        vector<ll> point;
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> sx[i] >> sy[i] >> tx[i] >> ty[i];
		
            point.push_back(sx[i]);
            point.push_back(sy[i]);
            point.push_back(tx[i]);
            point.push_back(ty[i]);
        }
	
        sort(point.begin(), point.end());
        point.erase(unique(point.begin(), point.end()), point.end());
        for (int i = 0; i < point.size(); i++) {
            zip[point[i]] = i;
        }
    }
	
    for (int i = 0; i < n; i++) {
        ll px, py;
        ll qx, qy;
		
        px = zip[sx[i]];
        py = zip[sy[i]];
        qx = zip[tx[i]];
        qy = zip[ty[i]];
        
        if (px > qx) swap(px, qx);
        if (py > qy) swap(py, qy);
		
        if (py == qy) {
            auto itr1 = x_p[py].lower_bound({px, qx});
            bool f = false;

            if (itr1 != x_p[py].end()) {
                if (itr1->first <= qx && qx <= itr1->second) {
                    f |= true;
                }
            }
            if (itr1 != x_p[py].begin()) {
                itr1--;
                if (itr1->first <= px && px <= itr1->second) {
                    f |= true;
                }
            }
            
            if (f ||
                query(py, px, qx, 1)) {
                cout << 0 << '\n';
            }
            else {
                cout << 1 << '\n';
                x_p[py].insert({px, qx});
                update(px, qx + 1, py, 0);
            }
        }
        else {
            auto itr1 = y_p[px].lower_bound({py, qy});
            bool f = false;

            if (itr1 != y_p[px].end()) {
                if (itr1->first <= qy && qy <= itr1->second) {
                    f |= true;
                }
            }
            if (itr1 != y_p[px].begin()) {
                itr1--;
                if (itr1->first <= py && py <= itr1->second) {
                    f |= true;
                }
            }
            
            if (f ||
                query(px, py, qy, 0)) {
                cout << 0 << '\n';
            }
            else {
                cout << 1 << '\n';
                y_p[px].insert({py, qy});
                update(py, qy + 1, px, 1);
            }
        }
    }
    
    return 0;
}
accuracy: 0.2
time_ms: 40
memory_kb: 138948
final_rank: 20