QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1111#546841#9173. Touching Grass11d10xyOIer_kzcFailed.2024-11-03 21:10:482024-11-04 17:10:28

Details

Extra Test:

Invalid Input

input:

1
1 1
1
1 1 1 1

output:


result:

FAIL Condition failed: "used_x.count(x1) == 0"

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#546841#9173. Touching GrassOIer_kzcAC ✓1060ms24988kbC++173.5kb2024-09-04 14:35:582024-09-04 14:35:59

answer

#include <stdio.h>
#include <string.h>

#include <vector>
#include <algorithm>

#define LOG(FMT...) fprintf(stderr, FMT)
#define eb emplace_back

using namespace std;

typedef long long LL;
constexpr int N = 800005, M = 300005;

char Bg;

struct Vec {
	int x, y;
	void read() {
		scanf("%d%d", &x, &y);
	}
	LL operator * (const Vec &t) const {
		return x * (LL)t.y - y * (LL)t.x;
	}
	void operator -= (const Vec &t) {
		x -= t.x, y -= t.y;
	}
	Vec operator - (const Vec &t) const {
		return (Vec){x - t.x, y - t.y};
	}
} q[N], bg[M], ve[M];
int lab[N];

int n, m;
int ord[M], szr, res[M];
int stk[N], tt;

bool was[M];
int a[M], b[M], c[M], sza, szb, szc;

char Ed;

void chkres(int i, int j) {
	if (bg[i].x <= q[j].x && q[j].x <= bg[i].x + ve[i].x && ve[i] * (q[j] - bg[i]) >= 0) {
		res[i] = j;
	}
}

bool cmpL(int i, int j) {
	return ve[i] * ve[j] >= 0;
}

LL area(int k, int i, int j) {
	k = lab[k], i = lab[i], j = lab[j];
	return (q[i] - q[k]) * (q[j] - q[k]);
}

void remerge(int ql, int pos1, int pos2) {
	szc = 0;
	int i = ql, j = pos1;
	while (i < pos1 || j < pos2) {
		if (j >= pos2 || i < pos1 && cmpL(ord[i], ord[j])) {
			c[szc++] = ord[i++];
		} else {
			c[szc++] = ord[j++];
		}
	}
	memcpy(ord + ql, c, szc << 2);
}

void solve(int l, int r, int ql, int qr) {
	// LOG("%d %d %d %d\n", l, r, ql, qr);
	if (ql > qr) {
		return;
	}
	tt = 0;
	for (int i = l; i <= r; ++i) {
		while (tt > 1 && area(stk[tt - 1], stk[tt], i) >= 0) {
			--tt;
		}
		stk[++tt] = i;
	}
	int cur = tt;
	int lefx = q[lab[l]].x, rigx = q[lab[r]].x;
	for (int k = ql, i; k <= qr; ++k) {
		i = ord[k];
		const auto &[bx, by] = bg[i];
		const auto &[vx, vy] = ve[i];
		// LOG("[%d, %d]\n", bx, bx + vx);
		if (bx > lefx || bx + vx < rigx) {
			continue;
		}
		// LOG("cur: %d\n", cur);
		was[i] = true;
		while (cur > 1 && (q[lab[stk[cur]]] - q[lab[stk[cur - 1]]]) * ve[i] >= 0) {
			cur -= 1;
		}
		chkres(i, lab[stk[cur]]);
	}
	if (l != r) {
		int mid = l + r >> 1;
		int midx = q[lab[mid]].x;
		sza = szb = szc = 0;
		for (int i = ql; i <= qr; ++i) {
			int k = ord[i];
			if (was[k]) {
				c[szc++] = k;
				continue;
			}
			if (bg[k].x <= midx) {
				a[sza++] = k;
			} else {
				b[szb++] = k;
			}
		}
		int pos1 = ql + sza, pos2 = pos1 + szb;
		memcpy(ord + ql, a, sza << 2);
		memcpy(ord + pos1, b, szb << 2);
		memcpy(ord + pos2, c, szc << 2);
		solve(l, mid, ql, ql + sza - 1);
		remerge(ql, pos1, pos2);
		midx = q[lab[mid + 1]].x;
		sza = szb = 0;
		for (int i = ql; i < pos2; ++i) {
			int k = ord[i];
			if (bg[k].x + ve[k].x >= midx) {
				a[sza++] = k;
			} else {
				b[szb++] = k;
			}
		}
		pos1 = ql + sza;
		memcpy(ord + ql, a, sza << 2);
		memcpy(ord + pos1, b, szb << 2);
		solve(mid + 1, r, ql, ql + sza - 1);
		remerge(ql, pos1, pos2);
		remerge(ql, pos2, qr + 1);
	}
	for (int k = ql; k <= qr; ++k) {
		was[ord[k]] = false;
	}
}

int main() {
	// LOG("MemoryUsed: %.3lf MB\n", (&Ed - &Bg) / 1048576.0);
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		q[i].read();
		lab[i] = i;
	}
	sort(lab + 1, lab + n + 1, [&](int a, int b) {
		return q[a].x < q[b].x;
	});
	scanf("%d", &m);
	memset(res + 1, -1, m << 2);
	for (int i = 1; i <= m; ++i) {
		bg[i].read(), ve[i].read();
		if (bg[i].x > ve[i].x) {
			swap(ve[i], bg[i]);
		}
		ve[i] -= bg[i];
		if (ve[i].x) {
			ord[++szr] = i;
		}
	}
	sort(ord + 1, ord + szr + 1, cmpL);
	solve(1, n, 1, szr);
	for (int i = 1; i <= m; ++i) {
		printf("%d\n", res[i]);
	}
	return 0;
}