Problem:
Problem I: Lapin Noir
ここは, 地面が正六角形を敷き詰めたマス目になっている街である. 各マスは, 下の図のように2 つの整数で表される.
ねこは(0, 0) のマスへ行こうとしている. いたずら好きの黒うさぎはこのことを知って, ねこの邪魔をしようと考えた.
黒うさぎはねこがいるマスへ跳び, その周りの6 マスのうち1 つまたは隣り合う2 つをブロックすることができる. ねこは周りの6 マスのうち, ブロックされていないマスを1 つ選んで進む. ねこが動くたび黒うさぎはねこを追いかけ, またブロックを行うことができる. 黒うさぎが動くと元のブロックは解除される. 下の図はブロックの様子を示している.
この街にはねこの縄張りとなっているマス目がいくつかある. 縄張りは正六角形の周をなすマス目の集合
n
個の合併として表される. 黒うさぎはねこの縄張りに立ち入ることはできるが, ブロックすることはできない.つまり, ねこは縄張り内であれば自由に動ける.
ねこの出発点の候補が
k
個あり, マス(
x
i
,
y
i
) (1 ≤
i
≤
k
) である. それぞれについて, ねこが必ず目的地(0, 0) に辿り着けるか, あるいは黒うさぎがうまく妨害することによってねこが目的地に辿り着けないかを判定せよ.
Input
1 行目:1 ≤
n
≤ 40 000
2 ∼ (
n
+ 1) 行目: ねこの縄張りを表す正六角形の頂点
(
n
+ 2) 行目: 1 ≤
k
≤ 40 000
(
n
+ 3) ∼ (
n
+
k
+ 2) 行目: ねこの出発点
x
i
,
y
i
−1 000 000 000 ≤ (各座標) ≤ 1 000 000 000
ねこの縄張りを表す正六角形は, 6 頂点の位置が反時計回りに与えられる.
Output
出発地の候補それぞれについて, ねこが必ず目的地(0,0) に辿り着けるなら”YES”を, あるいは黒うさぎがうまく妨害した場合ねこが目的地に辿り着けないなら”NO”を, 一行ずつ出力せよ.
Sample Input 1
2
1 -1 3 -1 3 1 1 3 -1 3 -1 1
3 0 4 0 4 1 3 2 2 2 2 1
3
1 1
-1 -1
2 4
Sample Output 1
YES
NO
YES

Submitted solutions:

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 40005

enum Type{
	X,
	Y,
	Z,
};

struct Info_L{
	Info_L(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_L &arg) const{

		return value < arg.value; //★昇順★
	}
	int value,index;
};

struct Info_R{
	Info_R(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_R &arg) const{

		return value > arg.value; //★降順★
	}
	int value,index;
};

struct Data{

	void set(int arg_min_x,int arg_max_x,int arg_min_y,int arg_max_y,int arg_min_z,int arg_max_z){
		X_L = arg_min_x;
		X_R = arg_max_x;
		Y_L = arg_min_y;
		Y_R = arg_max_y;
		Z_L = arg_min_z;
		Z_R = arg_max_z;
	}
	/*void  debug(){

		printf("X_L:%d X_R:%d\nY_L:%d Y_R:%d Z_L:%d Z_R:%d\n",X_L,X_R,Y_L,Y_R,Z_L,Z_R);
	}*/

	int X_L,X_R,Y_L,Y_R,Z_L,Z_R;
};

int N;
int can_L[3],can_R[3];
int next_can_L[3],next_can_R[3];
int index_L[3],index_R[3];
int next_L[3],next_R[3];
bool merged[SIZE];
vector<Info_L> L[3];
vector<Info_R> R[3];
Data data[SIZE];


bool is_Cross(int index){

	if((data[index].X_R < can_L[X]) || (data[index].X_L > can_R[X]) || (data[index].Y_R < can_L[Y])||
			(data[index].Y_L > can_R[Y]) || (data[index].Z_R < can_L[Z]) || (data[index].Z_L > can_R[Z])){

		return false;
	}

	//★★(0,0)スタートなので、縄張りの辺が安全地帯((0,0)が起源)の内部に含まれていなければいけない★★
	if((data[index].X_L >= can_L[X]) || (data[index].X_R <= can_R[X]) || (data[index].Y_L >= can_L[Y])||
			(data[index].Y_R <= can_R[Y])||(data[index].Z_L >= can_L[Z])||(data[index].Z_R <= can_R[Z])){

		return true;
	}

	return false;
}

bool is_OK(int tmp_x,int tmp_y){

	if((tmp_x < can_L[X]) || (tmp_x > can_R[X]) || (tmp_y < can_L[Y])||
			(tmp_y > can_R[Y]) || ((tmp_x+tmp_y) < can_L[Z]) || ((tmp_x+tmp_y) > can_R[Z])){

		return false;
	}

	if((tmp_x >= can_L[X]) || (tmp_x <= can_R[X]) || (tmp_y >= can_L[Y])||
			(tmp_y <= can_R[Y])||((tmp_x+tmp_y) >= can_L[Z])||((tmp_x+tmp_y) <= can_R[Z])){

		return true;
	}

	return false;
}


int main(){

	scanf("%d",&N);

	bool base_FLG = false;

	int work_x[6],work_y[6];

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

		next_can_L[i] = 0;
		next_can_R[i] = 0;
	}

	for(int loop = 0; loop < N; loop++){

		bool tmp_FLG = false;

		int min_x = (BIG_NUM+1),max_x = -(BIG_NUM+1);
		int min_y = (BIG_NUM+1),max_y = -(BIG_NUM+1);
		int min_z = (BIG_NUM+1),max_z = -(BIG_NUM+1);

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

			scanf("%d %d",&work_x[i],&work_y[i]);

			min_x = min(min_x,work_x[i]);
			max_x = max(max_x,work_x[i]);

			min_y = min(min_y,work_y[i]);
			max_y = max(max_y,work_y[i]);

			min_z = min(min_z,(work_x[i]+work_y[i]));
			max_z = max(max_z,(work_x[i]+work_y[i]));
		}
		data[loop].set(min_x,max_x,min_y,max_y,min_z,max_z);

		L[X].push_back(Info_L(min_x,loop));
		L[Y].push_back(Info_L(min_y,loop));
		L[Z].push_back(Info_L(min_z,loop));

		R[X].push_back(Info_R(max_x,loop));
		R[Y].push_back(Info_R(max_y,loop));
		R[Z].push_back(Info_R(max_z,loop));

		//(0,0)を調べる
		for(int i = 0; i < 6; i++){

			int xa = work_x[i],xb = work_x[(i+1)%6];
			int ya = work_y[i],yb = work_y[(i+1)%6];

			if((xa+ya == 0) && (xb+yb == 0) && min(xa,xb) <= 0 && max(xa,xb) >= 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
			if(xa == 0 && xb == 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
			if(ya == 0 && yb == 0 && min(xa,xb) <= 0 && max(xa,xb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
		}

		if(tmp_FLG){

			merged[loop] = true;

			next_can_L[X] = min(next_can_L[X],data[loop].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[loop].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[loop].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[loop].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[loop].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[loop].Z_R+1);
		}
	}

	if(!base_FLG){

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

		int tmp_x,tmp_y;

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

			scanf("%d %d",&tmp_x,&tmp_y);
			if(tmp_x == 0 && tmp_y == 0){

				printf("YES\n");

			}else{

				printf("NO\n");
			}
		}
		return 0;
	}

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

		sort(L[i].begin(),L[i].end());
		sort(R[i].begin(),R[i].end());

		index_L[i] = 0;
		index_R[i] = 0;
	}

	for(int i = 0; i < 3; i++){
		//★★(0,0)が縄張りの辺上にあったため★
		can_L[i] = next_can_L[i];
		can_R[i] = next_can_R[i];
	}

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

		merged[i] = false;
	}

	while(true){

		vector<int> vec;

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

			next_L[i] = index_L[i];
			next_R[i] = index_R[i];

			next_can_L[i] = can_L[i];
			next_can_R[i] = can_R[i];
		}

		//Lを見る
		for(int i = 0; i < 3; i++){
			while(next_L[i] < N && L[i][next_L[i]].value <= can_R[i])next_L[i]++;

			for(int k = index_L[i]; k < next_L[i]; k++){
				if(merged[L[i][k].index])continue;
				if(is_Cross(L[i][k].index)){

					vec.push_back(L[i][k].index);
				}
			}
		}

		//Rを見る
		for(int i = 0; i < 3; i++){
			while(next_R[i] < N && R[i][next_R[i]].value >= can_L[i])next_R[i]++;

			for(int k = index_R[i]; k < next_R[i]; k++){
				if(merged[R[i][k].index])continue;
				if(is_Cross(R[i][k].index)){

					vec.push_back(R[i][k].index);
				}
			}
		}

		if(vec.size() == 0)break;

		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());

		for(int i = 0; i < vec.size(); i++){

			merged[vec[i]] = true;

			next_can_L[X] = min(next_can_L[X],data[vec[i]].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[vec[i]].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[vec[i]].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[vec[i]].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[vec[i]].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[vec[i]].Z_R+1);
		}

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

			index_L[i] = next_L[i];
			index_R[i] = next_R[i];

			can_L[i] = next_can_L[i];
			can_R[i] = next_can_R[i];
		}
	}

	int num_query;
	int tmp_x,tmp_y;

	scanf("%d",&num_query);

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&tmp_x,&tmp_y);

		if(is_OK(tmp_x,tmp_y)){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 6220
final_rank: 2

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 40005

enum Type{
	X,
	Y,
	Z,
};

struct Info_L{
	Info_L(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_L &arg) const{

		return value < arg.value; //★昇順★
	}
	int value,index;
};

struct Info_R{
	Info_R(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_R &arg) const{

		return value > arg.value; //★降順★
	}
	int value,index;
};

struct Data{

	void set(int arg_min_x,int arg_max_x,int arg_min_y,int arg_max_y,int arg_min_z,int arg_max_z){
		X_L = arg_min_x;
		X_R = arg_max_x;
		Y_L = arg_min_y;
		Y_R = arg_max_y;
		Z_L = arg_min_z;
		Z_R = arg_max_z;
	}
	void  debug(){

		printf("X_L:%d X_R:%d\nY_L:%d Y_R:%d Z_L:%d Z_R:%d\n",X_L,X_R,Y_L,Y_R,Z_L,Z_R);
	}

	int X_L,X_R,Y_L,Y_R,Z_L,Z_R;
};

int N;
int can_L[3],can_R[3];
int next_can_L[3],next_can_R[3];
int index_L[3],index_R[3];
int next_L[3],next_R[3];
bool merged[SIZE];
vector<Info_L> L[3];
vector<Info_R> R[3];
Data data[SIZE];


bool is_Cross(int index){

	if((data[index].X_R < can_L[X]) || (data[index].X_L > can_R[X]) || (data[index].Y_R < can_L[Y])||
			(data[index].Y_L > can_R[Y]) || (data[index].Z_R < can_L[Z]) || (data[index].Z_L > can_R[Z])){

		return false;
	}

	if((data[index].X_L >= can_L[X]) || (data[index].X_R <= can_R[X]) || (data[index].Y_L >= can_L[Y])||
			(data[index].Y_R <= can_R[Y])||(data[index].Z_L >= can_L[Z])||(data[index].Z_R <= can_R[Z])){

		return true;
	}

	return false;
}

bool is_OK(int tmp_x,int tmp_y){

	if((tmp_x < can_L[X]) || (tmp_x > can_R[X]) || (tmp_y < can_L[Y])||
			(tmp_y > can_R[Y]) || ((tmp_x+tmp_y) < can_L[Z]) || ((tmp_x+tmp_y) > can_R[Z])){

		return false;
	}

	if((tmp_x >= can_L[X]) || (tmp_x <= can_R[X]) || (tmp_y >= can_L[Y])||
			(tmp_y <= can_R[Y])||((tmp_x+tmp_y) >= can_L[Z])||((tmp_x+tmp_y) <= can_R[Z])){

		return true;
	}

	return false;
}


int main(){

	scanf("%d",&N);

	bool base_FLG = false;

	int work_x[6],work_y[6];

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

		next_can_L[i] = 0;
		next_can_R[i] = 0;
	}

	for(int loop = 0; loop < N; loop++){

		bool tmp_FLG = false;

		int min_x = (BIG_NUM+1),max_x = -(BIG_NUM+1);
		int min_y = (BIG_NUM+1),max_y = -(BIG_NUM+1);
		int min_z = (BIG_NUM+1),max_z = -(BIG_NUM+1);

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

			scanf("%d %d",&work_x[i],&work_y[i]);

			min_x = min(min_x,work_x[i]);
			max_x = max(max_x,work_x[i]);

			min_y = min(min_y,work_y[i]);
			max_y = max(max_y,work_y[i]);

			min_z = min(min_z,(work_x[i]+work_y[i]));
			max_z = max(max_z,(work_x[i]+work_y[i]));
		}
		data[loop].set(min_x,max_x,min_y,max_y,min_z,max_z);

		L[X].push_back(Info_L(min_x,loop));
		L[Y].push_back(Info_L(min_y,loop));
		L[Z].push_back(Info_L(min_z,loop));

		R[X].push_back(Info_R(max_x,loop));
		R[Y].push_back(Info_R(max_y,loop));
		R[Z].push_back(Info_R(max_z,loop));

		//(0,0)を調べる
		for(int i = 0; i < 6; i++){

			int xa = work_x[i],xb = work_x[(i+1)%6];
			int ya = work_y[i],yb = work_y[(i+1)%6];

			if((xa+ya == 0) && (xb+yb == 0) && min(xa,xb) <= 0 && max(xa,xb) >= 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
			if(xa == 0 && xb == 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
			if(ya == 0 && yb == 0 && min(xa,xb) <= 0 && max(xa,xb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
		}

		if(tmp_FLG){

			merged[loop] = true;

			next_can_L[X] = min(next_can_L[X],data[loop].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[loop].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[loop].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[loop].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[loop].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[loop].Z_R+1);
		}
	}

	if(!base_FLG){

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

		int tmp_x,tmp_y;

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

			scanf("%d %d",&tmp_x,&tmp_y);
			if(tmp_x == 0 && tmp_y == 0){

				printf("YES\n");

			}else{

				printf("NO\n");
			}
		}
		return 0;
	}

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

		sort(L[i].begin(),L[i].end());
		sort(R[i].begin(),R[i].end());

		index_L[i] = 0;
		index_R[i] = 0;
	}

/*	for(int i = 0; i < N; i++){
		printf("data[%d] X_L:%d X_R:%d\nY_L:%d Y_R:%d\nZ_L:%d Z_R:%d\n",i,data[i].X_L,data[i].X_R,data[i].Y_L,data[i].Y_R,data[i].Z_L,data[i].Z_R);
	}*/

	for(int i = 0; i < 3; i++){
		//★★(0,0)が縄張りの辺上にあったため★
		can_L[i] = next_can_L[i];
		can_R[i] = next_can_R[i];
	}

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

		merged[i] = false;
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d  R:%d\n",i,can_L[i],can_R[i]);
	}*/

	while(true){

		vector<int> vec;

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

			next_L[i] = index_L[i];
			next_R[i] = index_R[i];

			next_can_L[i] = can_L[i];
			next_can_R[i] = can_R[i];
		}

		//Lを見る
		for(int i = 0; i < 3; i++){
			while(next_L[i] < N && L[i][next_L[i]].value <= can_R[i])next_L[i]++;

			for(int k = index_L[i]; k < next_L[i]; k++){
				if(merged[L[i][k].index])continue;
				if(is_Cross(L[i][k].index)){

					vec.push_back(L[i][k].index);
				}
			}
		}

		//Rを見る
		for(int i = 0; i < 3; i++){
			while(next_R[i] < N && R[i][next_R[i]].value >= can_L[i])next_R[i]++;

			for(int k = index_R[i]; k < next_R[i]; k++){
				if(merged[R[i][k].index])continue;
				if(is_Cross(R[i][k].index)){

					vec.push_back(R[i][k].index);
				}
			}
		}

		if(vec.size() == 0)break;

		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());

		for(int i = 0; i < vec.size(); i++){

			merged[vec[i]] = true;

		/*	printf("%dと交差\n",vec[i]);
			data[vec[i]].debug();
*/


			next_can_L[X] = min(next_can_L[X],data[vec[i]].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[vec[i]].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[vec[i]].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[vec[i]].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[vec[i]].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[vec[i]].Z_R+1);
		}

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

			index_L[i] = next_L[i];
			index_R[i] = next_R[i];

			can_L[i] = next_can_L[i];
			can_R[i] = next_can_R[i];
		}
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d can_R:%d\n",i,can_L[i],can_R[i]);
	}*/

	int num_query;
	int tmp_x,tmp_y;

	scanf("%d",&num_query);

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&tmp_x,&tmp_y);

		if(is_OK(tmp_x,tmp_y)){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 6212
final_rank: 1

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 40005

enum Type{
	X,
	Y,
	Z,
};

struct Info_L{
	Info_L(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_L &arg) const{

		return value < arg.value; //★昇順★
	}
	int value,index;
};

struct Info_R{
	Info_R(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_R &arg) const{

		return value > arg.value; //★降順★
	}
	int value,index;
};

struct Data{

	void set(int arg_min_x,int arg_max_x,int arg_min_y,int arg_max_y,int arg_min_z,int arg_max_z){
		X_L = arg_min_x;
		X_R = arg_max_x;
		Y_L = arg_min_y;
		Y_R = arg_max_y;
		Z_L = arg_min_z;
		Z_R = arg_max_z;
	}
	void  debug(){

		printf("X_L:%d X_R:%d\nY_L:%d Y_R:%d Z_L:%d Z_R:%d\n",X_L,X_R,Y_L,Y_R,Z_L,Z_R);
	}

	int X_L,X_R,Y_L,Y_R,Z_L,Z_R;
};

int N;
int can_L[3],can_R[3];
int next_can_L[3],next_can_R[3];
int index_L[3],index_R[3];
int next_L[3],next_R[3];
bool merged[SIZE];
vector<Info_L> L[3];
vector<Info_R> R[3];
Data data[SIZE];


bool is_Cross(int index){

	if((data[index].X_R < can_L[X]) || (data[index].X_L > can_R[X]) || (data[index].Y_R < can_L[Y])||
			(data[index].Y_L > can_R[Y]) || (data[index].Z_R < can_L[Z]) || (data[index].Z_L > can_R[Z])){

		return false;
	}

	if((data[index].X_L >= can_L[X]) || (data[index].X_R <= can_R[X]) || (data[index].Y_L >= can_L[Y])||
			(data[index].Y_R <= can_R[Y])||(data[index].Z_L >= can_L[Z])||(data[index].Z_R <= can_R[Z])){

		return true;
	}

	return false;
}

bool is_OK(int tmp_x,int tmp_y){

	if((tmp_x < can_L[X]) || (tmp_x > can_R[X]) || (tmp_y < can_L[Y])||
			(tmp_y > can_R[Y]) || ((tmp_x+tmp_y) < can_L[Z]) || ((tmp_x+tmp_y) > can_R[Z])){

		return false;
	}

	if((tmp_x >= can_L[X]) || (tmp_x <= can_R[X]) || (tmp_y >= can_L[Y])||
			(tmp_y <= can_R[Y])||((tmp_x+tmp_y) >= can_L[Z])||((tmp_x+tmp_y) <= can_R[Z])){

		return true;
	}

	return false;
}


int main(){

	scanf("%d",&N);

	bool base_FLG = false;

	int work_x[6],work_y[6];

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

		next_can_L[i] = 0;
		next_can_R[i] = 0;
	}

	for(int loop = 0; loop < N; loop++){

		bool tmp_FLG = false;

		int min_x = (BIG_NUM+1),max_x = -(BIG_NUM+1);
		int min_y = (BIG_NUM+1),max_y = -(BIG_NUM+1);
		int min_z = (BIG_NUM+1),max_z = -(BIG_NUM+1);

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

			scanf("%d %d",&work_x[i],&work_y[i]);

			min_x = min(min_x,work_x[i]);
			max_x = max(max_x,work_x[i]);

			min_y = min(min_y,work_y[i]);
			max_y = max(max_y,work_y[i]);

			min_z = min(min_z,(work_x[i]+work_y[i]));
			max_z = max(max_z,(work_x[i]+work_y[i]));
		}
		data[loop].set(min_x,max_x,min_y,max_y,min_z,max_z);

		L[X].push_back(Info_L(min_x,loop));
		L[Y].push_back(Info_L(min_y,loop));
		L[Z].push_back(Info_L(min_z,loop));

		R[X].push_back(Info_R(max_x,loop));
		R[Y].push_back(Info_R(max_y,loop));
		R[Z].push_back(Info_R(max_z,loop));

		//(0,0)を調べる
		for(int i = 0; i < 6; i++){

			int xa = work_x[i],xb = work_x[(i+1)%6];
			int ya = work_y[i],yb = work_y[(i+1)%6];

			if((xa+ya == 0) && (xb+yb == 0) && min(xa,xb) <= 0 && max(xa,xb) >= 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
			if(xa == 0 && xb == 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
			if(ya == 0 && yb == 0 && min(xa,xb) <= 0 && max(xa,xb) >= 0){

				tmp_FLG = true;
				base_FLG = true;
			}
		}

		if(tmp_FLG){

			merged[loop] = true;

			next_can_L[X] = min(next_can_L[X],data[loop].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[loop].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[loop].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[loop].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[loop].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[loop].Z_R+1);
		}
	}

	if(!base_FLG){

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

		int tmp_x,tmp_y;

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

			scanf("%d %d",&tmp_x,&tmp_y);
			if(tmp_x == 0 && tmp_y == 0){

				printf("YES\n");

			}else{

				printf("NO\n");
			}
		}
		return 0;
	}

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

		sort(L[i].begin(),L[i].end());
		sort(R[i].begin(),R[i].end());

		index_L[i] = 0;
		index_R[i] = 0;
	}

/*	for(int i = 0; i < N; i++){
		printf("data[%d] X_L:%d X_R:%d\nY_L:%d Y_R:%d\nZ_L:%d Z_R:%d\n",i,data[i].X_L,data[i].X_R,data[i].Y_L,data[i].Y_R,data[i].Z_L,data[i].Z_R);
	}*/

	for(int i = 0; i < 3; i++){
		//★★(0,0)が縄張りの辺上にあったため★
		can_L[i] = -1;
		can_R[i] = 1;
	}

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

		merged[i] = false;
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d  R:%d\n",i,can_L[i],can_R[i]);
	}*/

	while(true){

		vector<int> vec;

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

			next_L[i] = index_L[i];
			next_R[i] = index_R[i];

			next_can_L[i] = can_L[i];
			next_can_R[i] = can_R[i];
		}

		//Lを見る
		for(int i = 0; i < 3; i++){
			while(next_L[i] < N && L[i][next_L[i]].value <= can_R[i])next_L[i]++;

			for(int k = index_L[i]; k < next_L[i]; k++){
				if(merged[L[i][k].index])continue;
				if(is_Cross(L[i][k].index)){

					vec.push_back(L[i][k].index);
				}
			}
		}

		//Rを見る
		for(int i = 0; i < 3; i++){
			while(next_R[i] < N && R[i][next_R[i]].value >= can_L[i])next_R[i]++;

			for(int k = index_R[i]; k < next_R[i]; k++){
				if(merged[R[i][k].index])continue;
				if(is_Cross(R[i][k].index)){

					vec.push_back(R[i][k].index);
				}
			}
		}

		if(vec.size() == 0)break;

		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());

		for(int i = 0; i < vec.size(); i++){

			merged[vec[i]] = true;

		/*	printf("%dと交差\n",vec[i]);
			data[vec[i]].debug();
*/


			next_can_L[X] = min(next_can_L[X],data[vec[i]].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[vec[i]].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[vec[i]].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[vec[i]].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[vec[i]].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[vec[i]].Z_R+1);
		}

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

			index_L[i] = next_L[i];
			index_R[i] = next_R[i];

			can_L[i] = next_can_L[i];
			can_R[i] = next_can_R[i];
		}
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d can_R:%d\n",i,can_L[i],can_R[i]);
	}*/

	int num_query;
	int tmp_x,tmp_y;

	scanf("%d",&num_query);

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&tmp_x,&tmp_y);

		if(is_OK(tmp_x,tmp_y)){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}

	return 0;
}
accuracy: 0.56
time_ms: 30
memory_kb: 5172
final_rank: 9

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 40005

enum Type{
	X,
	Y,
	Z,
};

struct Info_L{
	Info_L(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_L &arg) const{

		return value < arg.value; //★昇順★
	}
	int value,index;
};

struct Info_R{
	Info_R(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_R &arg) const{

		return value > arg.value; //★降順★
	}
	int value,index;
};

struct Data{

	void set(int arg_min_x,int arg_max_x,int arg_min_y,int arg_max_y,int arg_min_z,int arg_max_z){
		X_L = arg_min_x;
		X_R = arg_max_x;
		Y_L = arg_min_y;
		Y_R = arg_max_y;
		Z_L = arg_min_z;
		Z_R = arg_max_z;
	}
	void  debug(){

		printf("X_L:%d X_R:%d\nY_L:%d Y_R:%d Z_L:%d Z_R:%d\n",X_L,X_R,Y_L,Y_R,Z_L,Z_R);
	}

	int X_L,X_R,Y_L,Y_R,Z_L,Z_R;
};

int N;
int can_L[3],can_R[3];
int next_can_L[3],next_can_R[3];
int index_L[3],index_R[3];
int next_L[3],next_R[3];
bool merged[SIZE];
vector<Info_L> L[3];
vector<Info_R> R[3];
Data data[SIZE];


bool is_Cross(int index){

	if((data[index].X_R < can_L[X]) || (data[index].X_L > can_R[X]) || (data[index].Y_R < can_L[Y])||
			(data[index].Y_L > can_R[Y]) || (data[index].Z_R < can_L[Z]) || (data[index].Z_L > can_R[Z])){

		return false;
	}

	if((data[index].X_L >= can_L[X]) || (data[index].X_R <= can_R[X]) || (data[index].Y_L >= can_L[Y])||
			(data[index].Y_R <= can_R[Y])||(data[index].Z_L >= can_L[Z])||(data[index].Z_R <= can_R[Z])){

		return true;
	}

	return false;
}

bool is_OK(int tmp_x,int tmp_y){

	if((tmp_x < can_L[X]) || (tmp_x > can_R[X]) || (tmp_y < can_L[Y])||
			(tmp_y > can_R[Y]) || ((tmp_x+tmp_y) < can_L[Z]) || ((tmp_x+tmp_y) > can_R[Z])){

		return false;
	}

	if((tmp_x >= can_L[X]) || (tmp_x <= can_R[X]) || (tmp_y >= can_L[Y])||
			(tmp_y <= can_R[Y])||((tmp_x+tmp_y) >= can_L[Z])||((tmp_x+tmp_y) <= can_R[Z])){

		return true;
	}

	return false;
}


int main(){

	scanf("%d",&N);

	bool base_FLG = false;

	int work_x[6],work_y[6];

	for(int loop = 0; loop < N; loop++){

		int min_x = (BIG_NUM+1),max_x = -(BIG_NUM+1);
		int min_y = (BIG_NUM+1),max_y = -(BIG_NUM+1);
		int min_z = (BIG_NUM+1),max_z = -(BIG_NUM+1);

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

			scanf("%d %d",&work_x[i],&work_y[i]);

			min_x = min(min_x,work_x[i]);
			max_x = max(max_x,work_x[i]);

			min_y = min(min_y,work_y[i]);
			max_y = max(max_y,work_y[i]);

			min_z = min(min_z,(work_x[i]+work_y[i]));
			max_z = max(max_z,(work_x[i]+work_y[i]));
		}
		data[loop].set(min_x,max_x,min_y,max_y,min_z,max_z);

		L[X].push_back(Info_L(min_x,loop));
		L[Y].push_back(Info_L(min_y,loop));
		L[Z].push_back(Info_L(min_z,loop));

		R[X].push_back(Info_R(max_x,loop));
		R[Y].push_back(Info_R(max_y,loop));
		R[Z].push_back(Info_R(max_z,loop));

		//(0,0)を調べる
		for(int i = 0; i < 6; i++){

			int xa = work_x[i],xb = work_x[(i+1)%6];
			int ya = work_y[i],yb = work_y[(i+1)%6];

			if((xa+ya == 0) && (xb+yb == 0) && min(xa,xb) <= 0 && max(xa,xb) >= 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				base_FLG = true;
			}
			if(xa == 0 && xb == 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				base_FLG = true;
			}
			if(ya == 0 && yb == 0 && min(xa,xb) <= 0 && max(xa,xb) >= 0){

				base_FLG = true;
			}
		}
	}

	if(!base_FLG){

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

		int tmp_x,tmp_y;

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

			scanf("%d %d",&tmp_x,&tmp_y);
			if(tmp_x == 0 && tmp_y == 0){

				printf("YES\n");

			}else{

				printf("NO\n");
			}
		}
		return 0;
	}

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

		sort(L[i].begin(),L[i].end());
		sort(R[i].begin(),R[i].end());

		index_L[i] = 0;
		index_R[i] = 0;
	}

/*	for(int i = 0; i < N; i++){
		printf("data[%d] X_L:%d X_R:%d\nY_L:%d Y_R:%d\nZ_L:%d Z_R:%d\n",i,data[i].X_L,data[i].X_R,data[i].Y_L,data[i].Y_R,data[i].Z_L,data[i].Z_R);
	}*/

	for(int i = 0; i < 3; i++){
		//★★(0,0)が縄張りの辺上にあったため★
		can_L[i] = -1;
		can_R[i] = 1;
	}

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

		merged[i] = false;
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d  R:%d\n",i,can_L[i],can_R[i]);
	}*/

	while(true){

		vector<int> vec;

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

			next_L[i] = index_L[i];
			next_R[i] = index_R[i];

			next_can_L[i] = can_L[i];
			next_can_R[i] = can_R[i];
		}

		//Lを見る
		for(int i = 0; i < 3; i++){
			while(next_L[i] < N && L[i][next_L[i]].value <= can_R[i])next_L[i]++;

			for(int k = index_L[i]; k < next_L[i]; k++){
				if(merged[L[i][k].index])continue;
				if(is_Cross(L[i][k].index)){

					vec.push_back(L[i][k].index);
				}
			}
		}

		//Rを見る
		for(int i = 0; i < 3; i++){
			while(next_R[i] < N && R[i][next_R[i]].value >= can_L[i])next_R[i]++;

			for(int k = index_R[i]; k < next_R[i]; k++){
				if(merged[R[i][k].index])continue;
				if(is_Cross(R[i][k].index)){

					vec.push_back(R[i][k].index);
				}
			}
		}

		if(vec.size() == 0)break;

		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());

		for(int i = 0; i < vec.size(); i++){

			merged[vec[i]] = true;

		/*	printf("%dと交差\n",vec[i]);
			data[vec[i]].debug();
*/


			next_can_L[X] = min(next_can_L[X],data[vec[i]].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[vec[i]].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[vec[i]].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[vec[i]].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[vec[i]].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[vec[i]].Z_R+1);
		}

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

			index_L[i] = next_L[i];
			index_R[i] = next_R[i];

			can_L[i] = next_can_L[i];
			can_R[i] = next_can_R[i];
		}
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d can_R:%d\n",i,can_L[i],can_R[i]);
	}*/

	int num_query;
	int tmp_x,tmp_y;

	scanf("%d",&num_query);

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&tmp_x,&tmp_y);

		if(is_OK(tmp_x,tmp_y)){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}

	return 0;
}
accuracy: 0.56
time_ms: 30
memory_kb: 5104
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 40005

enum Type{
	X,
	Y,
	Z,
};

struct Info_L{
	Info_L(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_L &arg) const{

		return value < arg.value; //★昇順★
	}
	int value,index;
};

struct Info_R{
	Info_R(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_R &arg) const{

		return value > arg.value; //★降順★
	}
	int value,index;
};

struct Data{

	void set(int arg_min_x,int arg_max_x,int arg_min_y,int arg_max_y,int arg_min_z,int arg_max_z){
		X_L = arg_min_x;
		X_R = arg_max_x;
		Y_L = arg_min_y;
		Y_R = arg_max_y;
		Z_L = arg_min_z;
		Z_R = arg_max_z;
	}
	void  debug(){

		printf("X_L:%d X_R:%d\nY_L:%d Y_R:%d Z_L:%d Z_R:%d\n",X_L,X_R,Y_L,Y_R,Z_L,Z_R);
	}

	int X_L,X_R,Y_L,Y_R,Z_L,Z_R;
};

int N;
int can_L[3],can_R[3];
int next_can_L[3],next_can_R[3];
int index_L[3],index_R[3];
int next_L[3],next_R[3];
bool merged[SIZE];
vector<Info_L> L[3];
vector<Info_R> R[3];
Data data[SIZE];


bool is_Cross(int index){

	if((data[index].X_R < can_L[X]) || (data[index].X_L > can_R[X]) || (data[index].Y_R < can_L[Y])||
			(data[index].Y_L > can_R[Y]) || (data[index].Z_R < can_L[Z]) || (data[index].Z_L > can_R[Z])){

		return false;
	}

	if((data[index].X_L >= can_L[X]) || (data[index].X_R <= can_R[X]) || (data[index].Y_L >= can_L[Y])||
			(data[index].Y_R <= can_R[Y])||(data[index].Z_L >= can_L[Z])||(data[index].Z_R <= can_R[Z])){

		return true;
	}

	return false;
}

bool is_OK(int tmp_x,int tmp_y){

	if((tmp_x < can_L[X]) || (tmp_x > can_R[X]) || (tmp_y < can_L[Y])||
			(tmp_y > can_R[Y]) || ((tmp_x+tmp_y) < can_L[Z]) || ((tmp_x+tmp_y) > can_R[Z])){

		return false;
	}

	if((tmp_x >= can_L[X]) || (tmp_x <= can_R[X]) || (tmp_y >= can_L[Y])||
			(tmp_y <= can_R[Y])||((tmp_x+tmp_y) >= can_L[Z])||((tmp_x+tmp_y) <= can_R[Z])){

		return true;
	}

	return false;
}


int main(){

	scanf("%d",&N);

	bool base_FLG = false;

	int work_x[6],work_y[6];

	for(int loop = 0; loop < N; loop++){

		int min_x = (BIG_NUM+1),max_x = -(BIG_NUM+1);
		int min_y = (BIG_NUM+1),max_y = -(BIG_NUM+1);
		int min_z = (BIG_NUM+1),max_z = -(BIG_NUM+1);

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

			scanf("%d %d",&work_x[i],&work_y[i]);

			min_x = min(min_x,work_x[i]);
			max_x = max(max_x,work_x[i]);

			min_y = min(min_y,work_y[i]);
			max_y = max(max_y,work_y[i]);

			min_z = min(min_z,(work_x[i]+work_y[i]));
			max_z = max(max_z,(work_x[i]+work_y[i]));
		}
		data[loop].set(min_x,max_x,min_y,max_y,min_z,max_z);

		L[X].push_back(Info_L(min_x,loop));
		L[Y].push_back(Info_L(min_y,loop));
		L[Z].push_back(Info_L(min_z,loop));

		R[X].push_back(Info_R(max_x,loop));
		R[Y].push_back(Info_R(max_y,loop));
		R[Z].push_back(Info_R(max_z,loop));

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

			int xa = work_x[i],xb = work_x[(i+1)%6];
			int ya = work_y[i],yb = work_y[(i+1)%6];

			if((xa+ya == 0) && (xb+yb == 0) && min(xa,xb) <= 0 && max(xa,xb) >= 0 && min(ya,yb) <= 0 && max(ya,yb) >= 0){

				base_FLG = true;
			}
		}
	}

	if(!base_FLG){

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

		int tmp_x,tmp_y;

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

			scanf("%d %d",&tmp_x,&tmp_y);
			if(tmp_x == 0 && tmp_y == 0){

				printf("YES\n");

			}else{

				printf("NO\n");
			}
		}
		return 0;
	}

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

		sort(L[i].begin(),L[i].end());
		sort(R[i].begin(),R[i].end());

		index_L[i] = 0;
		index_R[i] = 0;
	}

/*	for(int i = 0; i < N; i++){
		printf("data[%d] X_L:%d X_R:%d\nY_L:%d Y_R:%d\nZ_L:%d Z_R:%d\n",i,data[i].X_L,data[i].X_R,data[i].Y_L,data[i].Y_R,data[i].Z_L,data[i].Z_R);
	}*/

	for(int i = 0; i < 3; i++){
		//★★(0,0)が縄張りの辺上にあったため★
		can_L[i] = -1;
		can_R[i] = 1;
	}

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

		merged[i] = false;
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d  R:%d\n",i,can_L[i],can_R[i]);
	}*/

	while(true){

		vector<int> vec;

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

			next_L[i] = index_L[i];
			next_R[i] = index_R[i];

			next_can_L[i] = can_L[i];
			next_can_R[i] = can_R[i];
		}

		//Lを見る
		for(int i = 0; i < 3; i++){
			while(next_L[i] < N && L[i][next_L[i]].value <= can_R[i])next_L[i]++;

			for(int k = index_L[i]; k < next_L[i]; k++){
				if(merged[L[i][k].index])continue;
				if(is_Cross(L[i][k].index)){

					vec.push_back(L[i][k].index);
				}
			}
		}

		//Rを見る
		for(int i = 0; i < 3; i++){
			while(next_R[i] < N && R[i][next_R[i]].value >= can_L[i])next_R[i]++;

			for(int k = index_R[i]; k < next_R[i]; k++){
				if(merged[R[i][k].index])continue;
				if(is_Cross(R[i][k].index)){

					vec.push_back(R[i][k].index);
				}
			}
		}

		if(vec.size() == 0)break;

		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());

		for(int i = 0; i < vec.size(); i++){

			merged[vec[i]] = true;

		/*	printf("%dと交差\n",vec[i]);
			data[vec[i]].debug();
*/


			next_can_L[X] = min(next_can_L[X],data[vec[i]].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[vec[i]].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[vec[i]].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[vec[i]].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[vec[i]].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[vec[i]].Z_R+1);
		}

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

			index_L[i] = next_L[i];
			index_R[i] = next_R[i];

			can_L[i] = next_can_L[i];
			can_R[i] = next_can_R[i];
		}
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d can_R:%d\n",i,can_L[i],can_R[i]);
	}*/

	int num_query;
	int tmp_x,tmp_y;

	scanf("%d",&num_query);

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&tmp_x,&tmp_y);

		if(is_OK(tmp_x,tmp_y)){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}

	return 0;
}
accuracy: 0.12
time_ms: 30
memory_kb: 5128
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 40005

enum Type{
	X,
	Y,
	Z,
};

struct Info_L{
	Info_L(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_L &arg) const{

		return value < arg.value; //★昇順★
	}
	int value,index;
};

struct Info_R{
	Info_R(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_R &arg) const{

		return value > arg.value; //★降順★
	}
	int value,index;
};

struct Data{

	void set(int arg_min_x,int arg_max_x,int arg_min_y,int arg_max_y,int arg_min_z,int arg_max_z){
		X_L = arg_min_x;
		X_R = arg_max_x;
		Y_L = arg_min_y;
		Y_R = arg_max_y;
		Z_L = arg_min_z;
		Z_R = arg_max_z;
	}
	int X_L,X_R,Y_L,Y_R,Z_L,Z_R;
};

int N;
int can_L[3],can_R[3];
int next_can_L[3],next_can_R[3];
int index_L[3],index_R[3];
int next_L[3],next_R[3];
bool merged[SIZE];
vector<Info_L> L[3];
vector<Info_R> R[3];
Data data[SIZE];

bool is_Cross(int index){

	if((data[index].X_R < can_L[X]) || (data[index].X_L > can_R[X]) || (data[index].Y_R < can_L[Y])||
			(data[index].Y_L > can_R[Y]) || (data[index].Z_R < can_L[Z]) || (data[index].Z_L > can_R[Z])){

		return false;
	}

	if((data[index].X_L >= can_L[X]) || (data[index].X_R <= can_R[X]) || (data[index].Y_L >= can_L[Y])||
			(data[index].Y_R <= can_R[Y])||(data[index].Z_L >= can_L[Z])||(data[index].Z_R <= can_R[Z])){

		return true;
	}

	return false;
}

bool is_OK(int tmp_x,int tmp_y){

	if((tmp_x < can_L[X]) || (tmp_x > can_R[X]) || (tmp_y < can_L[Y])||
			(tmp_y > can_R[Y]) || ((tmp_x+tmp_y) < can_L[Z]) || ((tmp_x+tmp_y) > can_R[Z])){

		return false;
	}

	if((tmp_x >= can_L[X]) || (tmp_x <= can_R[X]) || (tmp_y >= can_L[Y])||
			(tmp_y <= can_R[Y])||((tmp_x+tmp_y) >= can_L[Z])||((tmp_x+tmp_y) <= can_R[Z])){

		return true;
	}

	return false;
}


int main(){

	scanf("%d",&N);

	int tmp_x,tmp_y;

	for(int loop = 0; loop < N; loop++){

		int min_x = (BIG_NUM+1),max_x = -(BIG_NUM+1);
		int min_y = (BIG_NUM+1),max_y = -(BIG_NUM+1);
		int min_z = (BIG_NUM+1),max_z = -(BIG_NUM+1);

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

			scanf("%d %d",&tmp_x,&tmp_y);

			min_x = min(min_x,tmp_x);
			max_x = max(max_x,tmp_x);

			min_y = min(min_y,tmp_y);
			max_y = max(max_y,tmp_y);

			min_z = min(min_z,(tmp_x+tmp_y));
			max_z = max(max_z,(tmp_x+tmp_y));
		}
		data[loop].set(min_x,max_x,min_y,max_y,min_z,max_z);

		L[X].push_back(Info_L(min_x,loop));
		L[Y].push_back(Info_L(min_y,loop));
		L[Z].push_back(Info_L(min_z,loop));

		R[X].push_back(Info_R(max_x,loop));
		R[Y].push_back(Info_R(max_y,loop));
		R[Z].push_back(Info_R(max_z,loop));
	}

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

		sort(L[i].begin(),L[i].end());
		sort(R[i].begin(),R[i].end());

		index_L[i] = 0;
		index_R[i] = 0;
	}

/*	for(int i = 0; i < N; i++){
		printf("data[%d] X_L:%d X_R:%d\nY_L:%d Y_R:%d\nZ_L:%d Z_R:%d\n",i,data[i].X_L,data[i].X_R,data[i].Y_L,data[i].Y_R,data[i].Z_L,data[i].Z_R);
	}*/

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

		can_L[i] = 0;
		can_R[i] = 0;
	}

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

		merged[i] = false;
	}

	while(true){

		vector<int> vec;

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

			next_L[i] = index_L[i];
			next_R[i] = index_R[i];

			next_can_L[i] = can_L[i];
			next_can_R[i] = can_R[i];
		}

		//Lを見る
		for(int i = 0; i < 3; i++){
			while(next_L[i] < N && L[i][next_L[i]].value <= can_R[i])next_L[i]++;

			for(int k = index_L[i]; k < next_L[i]; k++){
				if(merged[L[i][k].index])continue;
				if(is_Cross(L[i][k].index)){

					vec.push_back(L[i][k].index);
				}
			}
		}

		//Rを見る
		for(int i = 0; i < 3; i++){
			while(next_R[i] < N && R[i][next_R[i]].value >= can_L[i])next_R[i]++;

			for(int k = index_R[i]; k < next_R[i]; k++){
				if(merged[R[i][k].index])continue;
				if(is_Cross(R[i][k].index)){

					vec.push_back(R[i][k].index);
				}
			}
		}

		if(vec.size() == 0)break;

		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());

		for(int i = 0; i < vec.size(); i++){

			merged[vec[i]] = true;

			next_can_L[X] = min(next_can_L[X],data[vec[i]].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[vec[i]].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[vec[i]].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[vec[i]].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[vec[i]].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[vec[i]].Z_R+1);
		}

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

			index_L[i] = next_L[i];
			index_R[i] = next_R[i];

			can_L[i] = next_can_L[i];
			can_R[i] = next_can_R[i];
		}
	}

	/*for(int i = 0; i < 3; i++){

		printf("can_L[%d]:%d can_R:%d\n",i,can_L[i],can_R[i]);
	}*/

	int num_query;

	scanf("%d",&num_query);

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&tmp_x,&tmp_y);

		if(is_OK(tmp_x,tmp_y)){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}

	return 0;
}
accuracy: 0.56
time_ms: 30
memory_kb: 5156
final_rank: 8

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 40005

enum Type{
	X,
	Y,
	Z,
};

struct Info_L{
	Info_L(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_L &arg) const{

		return value < arg.value; //★昇順★
	}
	int value,index;
};

struct Info_R{
	Info_R(int arg_value,int arg_index){
		value = arg_value;
		index = arg_index;
	}
	bool operator<(const struct Info_R &arg) const{

		return value > arg.value; //★降順★
	}
	int value,index;
};

struct Data{

	void set(int arg_min_x,int arg_max_x,int arg_min_y,int arg_max_y,int arg_min_z,int arg_max_z){
		X_L = arg_min_x;
		X_R = arg_max_x;
		Y_L = arg_min_y;
		Y_R = arg_max_y;
		Z_L = arg_min_z;
		Z_R = arg_max_z;
	}
	int X_L,X_R,Y_L,Y_R,Z_L,Z_R;
};

int N;
int can_L[3],can_R[3];
int next_can_L[3],next_can_R[3];
int index_L[3],index_R[3];
int next_L[3],next_R[3];
bool merged[SIZE];
vector<Info_L> L[3];
vector<Info_R> R[3];
Data data[SIZE];

bool is_Cross(int index){

	if((data[index].X_R < can_L[X]) || (data[index].X_L > can_R[X]) || (data[index].Y_R < can_L[Y])||
			(data[index].Y_L > can_R[Y]) || (data[index].Z_R < can_L[Z]) || (data[index].Z_L > can_R[Z])){

		return false;
	}

	if((data[index].X_L >= can_L[X]) || (data[index].X_R <= can_R[X]) || (data[index].Y_L >= can_L[Y])||
			(data[index].Y_R <= can_R[Y])||(data[index].Z_L >= can_L[Z])||(data[index].Z_R <= can_R[Z])){

		return true;
	}

	return false;
}


int main(){

	scanf("%d",&N);

	int tmp_x,tmp_y;

	for(int loop = 0; loop < N; loop++){

		int min_x = (BIG_NUM+1),max_x = -(BIG_NUM+1);
		int min_y = (BIG_NUM+1),max_y = -(BIG_NUM+1);
		int min_z = (BIG_NUM+1),max_z = -(BIG_NUM+1);

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

			scanf("%d %d",&tmp_x,&tmp_y);

			min_x = min(min_x,tmp_x);
			max_x = max(max_x,tmp_x);

			min_y = min(min_y,tmp_y);
			max_y = max(max_y,tmp_y);

			min_z = min(min_z,(tmp_x+tmp_y));
			max_z = max(max_z,(tmp_x+tmp_y));
		}
		data[loop].set(min_x,max_x,min_y,max_y,min_z,max_z);

		L[X].push_back(Info_L(min_x,loop));
		L[Y].push_back(Info_L(min_y,loop));
		L[Z].push_back(Info_L(min_z,loop));

		R[X].push_back(Info_R(max_x,loop));
		R[Y].push_back(Info_R(max_y,loop));
		R[Z].push_back(Info_R(max_z,loop));
	}

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

		sort(L[i].begin(),L[i].end());
		sort(R[i].begin(),R[i].end());

		index_L[i] = 0;
		index_R[i] = 0;
	}

/*	for(int i = 0; i < N; i++){
		printf("data[%d] X_L:%d X_R:%d\nY_L:%d Y_R:%d\nZ_L:%d Z_R:%d\n",i,data[i].X_L,data[i].X_R,data[i].Y_L,data[i].Y_R,data[i].Z_L,data[i].Z_R);
	}*/

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

		can_L[i] = 0;
		can_R[i] = 0;
	}

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

		merged[i] = false;
	}

	while(true){

		vector<int> vec;

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

			next_L[i] = index_L[i];
			next_R[i] = index_R[i];

			next_can_L[i] = can_L[i];
			next_can_R[i] = can_R[i];
		}

		//Lを見る
		for(int i = 0; i < 3; i++){
			while(next_L[i] < N && L[i][next_L[i]].value <= can_R[i])next_L[i]++;

			for(int k = index_L[i]; k < next_L[i]; k++){
				if(merged[L[i][k].index])continue;
				if(is_Cross(L[i][k].index)){

					vec.push_back(L[i][k].index);
				}
			}
		}

		//Rを見る
		for(int i = 0; i < 3; i++){
			while(next_R[i] < N && R[i][next_R[i]].value >= can_L[i])next_R[i]++;

			for(int k = index_R[i]; k < next_R[i]; k++){
				if(merged[R[i][k].index])continue;
				if(is_Cross(R[i][k].index)){

					vec.push_back(R[i][k].index);
				}
			}
		}

		if(vec.size() == 0)break;

		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());

		for(int i = 0; i < vec.size(); i++){

			merged[vec[i]] = true;

			next_can_L[X] = min(next_can_L[X],data[vec[i]].X_L-1);
			next_can_R[X] = max(next_can_R[X],data[vec[i]].X_R+1);

			next_can_L[Y] = min(next_can_L[Y],data[vec[i]].Y_L-1);
			next_can_R[Y] = max(next_can_R[Y],data[vec[i]].Y_R+1);

			next_can_L[Z] = min(next_can_L[Z],data[vec[i]].Z_L-1);
			next_can_R[Z] = max(next_can_R[Z],data[vec[i]].Z_R+1);
		}

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

			index_L[i] = next_L[i];
			index_R[i] = next_R[i];

			can_L[i] = next_can_L[i];
			can_R[i] = next_can_R[i];
		}
	}

	int num_query;

	scanf("%d",&num_query);

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&tmp_x,&tmp_y);

		if(tmp_x >= can_L[X] && tmp_x <= can_R[X] && tmp_y >= can_L[Y] &&
				tmp_y <= can_R[Y] && (tmp_x+tmp_y) >= can_L[Z] && (tmp_x+tmp_y) <= can_R[Z]){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}

	return 0;
}
accuracy: 0.56
time_ms: 40
memory_kb: 5136
final_rank: 10

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

typedef long long ll;
typedef pair<int, int> i_i;
int MOD = 1000000007;

int main() {
	int n; cin >> n;
	vector<int> X, Y;
	while (n--) {
		vector<int> x(6), y(6);
		for (int j = 0; j < 6; j++)
			scanf("%d%d", &x[j], &y[j]);
		for (int j = 0; j < 6; j++) {
			for (int k = 0; k < 3; k++) {
				X.push_back(x[j]);
				Y.push_back(y[j]);
			}
			for (int k = 0; k < 3; k++) {
				X.push_back(x[(j + 1) % 6]);
				Y.push_back(y[(j + 1) % 6]);
			}
		}
	}
	n = X.size() / 6;
	vector<vector<int> > a(n, vector<int>(6, INT_MIN));
	vector<vector<i_i> > p(6, vector<i_i>(n));
	int hoge = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < 6; j++) {
			int x = X[hoge], y = Y[hoge]; hoge++;
			a[i][0] = max(a[i][0], x);
			a[i][1] = max(a[i][1], -x);
			a[i][2] = max(a[i][2], y);
			a[i][3] = max(a[i][3], -y);
			a[i][4] = max(a[i][4], x + y);
			a[i][5] = max(a[i][5], -(x + y));
		}
		for (int k = 0; k < 6; k++)
			p[k][i] = i_i(a[i][k], i);
	}
	for (int k = 0; k < 6; k++) {
		sort(p[k].begin(), p[k].end());
		reverse(p[k].begin(), p[k].end());
	}
	vector<int> index(6), cnt(n);
	queue<int> q;
	vector<int> b(6);
	for (;;) {
		for (int k = 0; k < 6; k++)
			for (int& i = index[k]; i < n && -p[k][i].first <= b[k ^ 1]; i++) {
				int j = p[k][i].second;
				if (++cnt[j] == 6) q.push(j);
			}
		if (q.empty()) break;
		int i = q.front(); q.pop();
		for (int k = 0; k < 6; k++)
			b[k] = max(b[k], a[i][k] + 1);
	}
	int k; cin >> k;
	while (k--) {
		int x, y; scanf("%d%d", &x, &y);
		if (x <= b[0] && -x <= b[1] && y <= b[2] && -y <= b[3] && x + y <= b[4] && -(x + y) <= b[5])
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
}
accuracy: 1
time_ms: 250
memory_kb: 42420
final_rank: 6

code_snippet: #include<cstdio>
#include<queue>
#include<vector>
#include<utility>
#include<algorithm>

using namespace std;

typedef pair<int,int> P;

int xs[40400][7],ys[40400][7];

vector<P> vals[6];

int N;
int cnt[40400*6];

queue<int> que;
bool used[40400];

int Q;
int qx[40400],qy[40400];

int main(){
	scanf("%d",&N);
	bool suc=true;
	for(int i=0;i<N;i++){
		for(int j=0;j<6;j++){
			scanf("%d%d",&xs[i][j],&ys[i][j]);
		}
		xs[i][6]=xs[i][0],ys[i][6]=ys[i][0];
		for(int j=0;j<6;j++){
			if(xs[i][j]==0&&xs[i][j+1]==0&&(long long)ys[i][j]*ys[i][j+1]<=0) suc=true;
			if(ys[i][j]==0&&ys[i][j+1]==0&&(long long)xs[i][j]*xs[i][j+1]<=0) suc=true;
			if(xs[i][j]+ys[i][j]==0&&xs[i][j+1]+ys[i][j+1]==0&&
				(long long)xs[i][j]*xs[i][j+1]<=0) suc=true;
		}
	}
	scanf("%d",&Q);
	for(int i=0;i<Q;i++){
		scanf("%d%d",qx+i,qy+i);
	}
	if(suc==false){
		for(int i=0;i<Q;i++){
			if(qx[i]==0&&qy[i]==0) printf("YES\n");
			else printf("NO\n");
		}
		return 0;
	}
	for(int i=0;i<N;i++){
		for(int j=0;j<6;j++){
			int x0=xs[i][j],x1=xs[i][j+1];
			int y0=ys[i][j],y1=ys[i][j+1];
			int z0=xs[i][j]+ys[i][j],z1=xs[i][j+1]+ys[i][j+1];
			if(x0>x1) swap(x0,x1);
			if(y0>y1) swap(y0,y1);
			if(z0>z1) swap(z0,z1);
			int tmp[]={x0,-x1,y0,-y1,z0,-z1};
			for(int k=0;k<6;k++){
				vals[k].push_back(P(tmp[k],i*6+j));
			}
		}
	}
	for(int i=0;i<6;i++){
		sort(vals[i].begin(),vals[i].end());
	}
	int ids[6]={};
	int res[6]={};
	for(int i=0;i<6;i++){
		for(ids[i]=0;ids[i]<vals[i].size();ids[i]++){
			if(vals[i][ids[i]].first<=0){
				int id=vals[i][ids[i]].second;
				cnt[id]++;
				if(cnt[id]==6){
					int id2=id/6;
					if(used[id2]) continue;
					used[id2]=true;
					que.push(id2);
				}
			}else{
				break;
			}
		}
	}
//	for(int i=0;i<vals[0].size();i++) printf("%d ",vals[0][i]);
//	printf("\n");
	while(!que.empty()){
		int id=que.front();
		que.pop();
		int tmp[6]={};
		for(int j=0;j<6;j++){
			tmp[0]=max(tmp[0],xs[id][j]+1);
			tmp[1]=max(tmp[1],-xs[id][j]+1);
			tmp[2]=max(tmp[2],ys[id][j]+1);
			tmp[3]=max(tmp[3],-ys[id][j]+1);
			tmp[4]=max(tmp[4],xs[id][j]+ys[id][j]+1);
			tmp[5]=max(tmp[5],-(xs[id][j]+ys[id][j])+1);
		}
//		printf("id=%d\n",id);
//		printf("tmp={");
//		for(int j=0;j<6;j++){
//			printf("%d,",tmp[j]);
//		}
//		printf("}\n");
		for(int j=0;j<6;j++){
			res[j]=max(res[j],tmp[j]);
		}
		for(int j=0;j<6;j++){
//			printf("j=%d\n",j);
//			printf("ids[j]=%d,vals[j][ids[j]]=%d\n",ids[j],vals[j][ids[j]]);
			while(ids[j]<vals[j].size()&&vals[j][ids[j]].first<=tmp[j]){
				int id=vals[j][ids[j]].second;
//				printf("%d++\n",id);
				cnt[id]++;
				if(cnt[id]==6){
					int id2=id/6;
					if(used[id2]){
						goto nextloop;
					}
					used[id2]=true;
					que.push(id2);
				}
				nextloop: ids[j]++;
			}
		}
	}
/*	int res[6];
	for(int i=0;i<6;i++){
		res[i]=vals[i][ids[i]-1].first;
		if(i%2==1) res[i]*=-1;
	}*/
	for(int i=0;i<6;i++){
		if(i%2==1) res[i]*=-1;
	}
//	for(int i=0;i<6;i++) printf("%d ",res[i]);
//	printf("\n");
//	for(int i=6;i<12;i++) printf("%d ",cnt[i]);
//	printf("\n");
	for(int q=0;q<Q;q++){
		bool ok=true;
		if((qx[q]<res[1])) ok=false;
		if((res[0]<qx[q])) ok=false;
		if((qy[q]<res[3])) ok=false;
		if((res[2]<qy[q])) ok=false;
		if((qx[q]+qy[q]<res[5])) ok=false;
		if((res[4]<qx[q]+qy[q])) ok=false;
		if(ok) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 16032
final_rank: 5

code_snippet: #include<stdio.h>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int x[41000][6];
int y[41000][6];
int z[41000][6];
int tx[41000];
int ty[41000];
int tz[41000];
pair<int,int> ex[81000];
pair<int,int> ey[81000];
pair<int,int> ez[81000];
int zx[81000];
int zy[81000];
int zz[81000];
int cnt[41000];
int u[41000];
int v[41000];
int main(){
	int a;
	scanf("%d",&a);
	for(int i=0;i<a;i++){
		for(int j=0;j<6;j++)scanf("%d%d",&x[i][j],&y[i][j]);
		for(int j=0;j<6;j++)z[i][j]=x[i][j]+y[i][j];
	}
	for(int i=0;i<a;i++){
		zx[i*2]=1010101010;
		zx[i*2+1]=-1010101010;
		zy[i*2]=1010101010;
		zy[i*2+1]=-1010101010;
		zz[i*2]=1010101010;
		zz[i*2+1]=-1010101010;
		for(int j=0;j<6;j++){
			zx[i*2]=min(zx[i*2],x[i][j]);
			zx[i*2+1]=max(zx[i*2+1],x[i][j]);
			zy[i*2]=min(zy[i*2],y[i][j]);
			zy[i*2+1]=max(zy[i*2+1],y[i][j]);
			zz[i*2]=min(zz[i*2],z[i][j]);
			zz[i*2+1]=max(zz[i*2+1],z[i][j]);
		}
		ex[i*2]=make_pair(zx[i*2],i*2);
		ex[i*2+1]=make_pair(zx[i*2+1],i*2+1);
		ey[i*2]=make_pair(zy[i*2],i*2);
		ey[i*2+1]=make_pair(zy[i*2+1],i*2+1);
		ez[i*2]=make_pair(zz[i*2],i*2);
		ez[i*2+1]=make_pair(zz[i*2+1],i*2+1);
		
	}
	for(int i=0;i<a;i++){
		if(zx[i*2+1]>=0)cnt[i]++;
		if(zx[i*2]<=0)cnt[i]++;
		if(zy[i*2+1]>=0)cnt[i]++;
		if(zy[i*2]<=0)cnt[i]++;
		if(zz[i*2+1]>=0)cnt[i]++;
		if(zz[i*2]<=0)cnt[i]++;
	}
	for(int i=0;i<a;i++){
		if(zx[i*2+1]<=0)u[i]++;
		if(zx[i*2]>=0)u[i]++;
		if(zy[i*2+1]<=0)u[i]++;
		if(zy[i*2]>=0)u[i]++;
		if(zz[i*2+1]<=0)u[i]++;
		if(zz[i*2]>=0)u[i]++;
	}
	queue<int>Q;
	for(int i=0;i<a;i++){
		if(cnt[i]==6&&u[i]){
			v[i]=1;
			Q.push(i);
		}
	}
	std::sort(ex,ex+a*2);
	std::sort(ey,ey+a*2);
	std::sort(ez,ez+a*2);
	int b;
	scanf("%d",&b);
	for(int i=0;i<b;i++){
		scanf("%d%d",tx+i,ty+i);
		tz[i]=tx[i]+ty[i];
	}
	int xl=0;
	int xr=0;
	int yl=0;
	int yr=0;
	int zl=0;
	int zr=0;
	while(1){
		int XL=xl;
		int XR=xr;
		int YL=yl;
		int YR=yr;
		int ZL=zl;
		int ZR=zr;
		while(Q.size()){
			int at=Q.front();
			Q.pop();
			XL=min(XL,zx[at*2]-1);
			XR=max(XR,zx[at*2+1]+1);
			YL=min(YL,zy[at*2]-1);
			YR=max(YR,zy[at*2+1]+1);
			ZL=min(ZL,zz[at*2]-1);
			ZR=max(ZR,zz[at*2+1]+1);
		}
	//	printf("%d %d %d %d %d %d\n",XL,XR,YL,YR,ZL,ZR);
		if(XL==xl&&XR==xr&&YL==yl&&YR==yr&&ZL==zl&&ZR==zr)break;
		int L=lower_bound(ex,ex+a*2,make_pair(XL,0))-ex;
		int R=lower_bound(ex,ex+a*2,make_pair(xl,0))-ex;
		for(int i=L;i<R;i++){
			int at=ex[i].second;
			if(at%2)cnt[at/2]++;
			else u[at/2]++;
			if(!v[at/2]&&u[at/2]&&cnt[at/2]==6){
				v[at/2]=1;
				Q.push(at/2);
			}
		}
		L=lower_bound(ex,ex+a*2,make_pair(xr,99999999))-ex;
		R=lower_bound(ex,ex+a*2,make_pair(XR,99999999))-ex;
		for(int i=L;i<R;i++){
			int at=ex[i].second;
			if(at%2)u[at/2]++;
			else cnt[at/2]++;
			if(!v[at/2]&&u[at/2]&&cnt[at/2]==6){
				v[at/2]=1;
				Q.push(at/2);
			}
		}
		L=lower_bound(ey,ey+a*2,make_pair(YL,0))-ey;
		R=lower_bound(ey,ey+a*2,make_pair(yl,0))-ey;
		for(int i=L;i<R;i++){
			int at=ey[i].second;
			if(at%2)cnt[at/2]++;
			else u[at/2]++;
			if(!v[at/2]&&u[at/2]&&cnt[at/2]==6){
				v[at/2]=1;
				Q.push(at/2);
			}
		}
		L=lower_bound(ey,ey+a*2,make_pair(yr,99999999))-ey;
		R=lower_bound(ey,ey+a*2,make_pair(YR,99999999))-ey;
		for(int i=L;i<R;i++){
			int at=ey[i].second;
			if(at%2)u[at/2]++;
			else cnt[at/2]++;
			if(!v[at/2]&&u[at/2]&&cnt[at/2]==6){
				v[at/2]=1;
				Q.push(at/2);
			}
		}
		L=lower_bound(ez,ez+a*2,make_pair(ZL,0))-ez;
		R=lower_bound(ez,ez+a*2,make_pair(zl,0))-ez;
		for(int i=L;i<R;i++){
			int at=ez[i].second;
			if(at%2)cnt[at/2]++;
			else u[at/2]++;
			if(!v[at/2]&&u[at/2]&&cnt[at/2]==6){
				v[at/2]=1;
				Q.push(at/2);
			}
		}
		L=lower_bound(ez,ez+a*2,make_pair(zr,99999999))-ez;
		R=lower_bound(ez,ez+a*2,make_pair(ZR,99999999))-ez;
		for(int i=L;i<R;i++){
			int at=ez[i].second;
			if(at%2)u[at/2]++;
			else cnt[at/2]++;
			if(!v[at/2]&&u[at/2]&&cnt[at/2]==6){
				v[at/2]=1;
				Q.push(at/2);
			}
		}
		xl=XL;xr=XR;yl=YL;yr=YR;zl=ZL;zr=ZR;
	}
	for(int i=0;i<b;i++){
		if(xl<=tx[i]&&tx[i]<=xr&&yl<=ty[i]&&ty[i]<=yr&&zl<=tz[i]&&tz[i]<=zr)printf("YES\n");
		else printf("NO\n");
	}
}
accuracy: 1
time_ms: 100
memory_kb: 7708
final_rank: 3

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (ll i = 0; i < (ll)(n); i++)
#define FOR(i, s, n) for (ll i = (s); i < (ll)(n); i++)
#define FOREQ(i, s, n) for (ll i = (s); i <= (ll)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Hexagon {
  ll vs[3][2];
  Hexagon() {;}
};

Hexagon S;
Hexagon territory[40010];
deque<pair<ll, ll> > dists1[3][2];
deque<pair<ll, ll> > dists2[3][2];
ll state[40010];

void Expand(ll index) {
  Hexagon s = territory[index];
  REP(k, 3) {
    s.vs[k][0]--;
    s.vs[k][1]++;
  }
  REP(k, 3) REP(type, 2) {
    S.vs[k][0] = min(S.vs[k][0], s.vs[k][type]);
    S.vs[k][1] = max(S.vs[k][1], s.vs[k][type]);
  }
}

ll Check() {
  ll ret = 0;
  REP(k, 3) {
    REP(type, 2) {
      while (!dists1[k][type].empty()) {
        ll d = S.vs[k][type ^ 1];
        if (type == 0) {
          if (dists1[k][0].front().first > d) { break; }
        } else {
          if (d > -dists1[k][1].front().first) { break; }
        }
        ll index = dists1[k][type].front().second;
        state[index] |= 1 << (k * 2 + type);
        //cout << index << " " << k * 2 + type << endl;
        //cout << state[index] << " " << (1 << 7) - 1 << endl;
        if (state[index] == (1 << 7) - 1) {
          state[index] = 0;
          Expand(index);
          ret++;
        }
        dists1[k][type].pop_front();
      }
      while (!dists2[k][type].empty()) {
        ll d = S.vs[k][type];
        if (type == 0) {
          if (-dists2[k][type].front().first < d) { break; }
        } else {
          if (d < dists2[k][type].front().first) { break; }
        }
        ll index = dists2[k][type].front().second;
        //cout << index << endl;
        state[index] |= 1 << 6;
        if (state[index] == (1 << 7) - 1) {
          state[index] = 0;
          Expand(index);
          ret++;
        }
        dists2[k][type].pop_front();
      }
    }
  }
  return ret;
}

ll n, q;
int main() {
  while (scanf("%lld", &n) > 0) {
    MEMSET(state, 0);
    REP(k, 3) REP(type, 2) {
      dists1[k][type].clear();
      dists2[k][type].clear();
    }
    REP(i, n) {
      Hexagon hex;
      REP(j, 3) {
        hex.vs[j][0] = 1LL << 60;
        hex.vs[j][1] = -(1LL << 60);
      }
      REP(j, 6) {
        ll x, y;
        scanf("%lld %lld", &x, &y);
        ll z = x + y;
        ll v[3] = { x, y, z };
        REP(k, 3) {
          hex.vs[k][0] = min(hex.vs[k][0], v[k]);
          hex.vs[k][1] = max(hex.vs[k][1], v[k]);
        }
      }
      territory[i] = hex;
      REP(k, 3) {
        dists1[k][0].push_back(make_pair(hex.vs[k][0], i));
        dists1[k][1].push_back(make_pair(-hex.vs[k][1], i));
        dists2[k][0].push_back(make_pair(-hex.vs[k][0], i));
        dists2[k][1].push_back(make_pair(hex.vs[k][1], i));
      }
    }
    REP(k, 3) REP(type, 2) {
      sort(dists1[k][type].begin(), dists1[k][type].end());
      sort(dists2[k][type].begin(), dists2[k][type].end());
    }
    REP(k, 3) REP(l, 2) { S.vs[k][l] = 0; }
    while (Check()) {;}
    // REP(k, 3) {
    //   cout << S.vs[k][0] << " " << S.vs[k][1] << endl;
    // }
    scanf("%lld", &q);
    REP(i, q) {
      ll x, y;
      scanf("%lld %lld", &x, &y);
      ll z = x + y;
      if (S.vs[0][0] <= x && x <= S.vs[0][1] &&
          S.vs[1][0] <= y && y <= S.vs[1][1] &&
          S.vs[2][0] <= z && z <= S.vs[2][1]) {
        puts("YES");
      } else {
        puts("NO");
      }
    }
  }
}
accuracy: 1
time_ms: 190
memory_kb: 10000
final_rank: 4