제출 #381236

#제출 시각아이디문제언어결과실행 시간메모리
381236rainboy새 집 (APIO18_new_home)C11
22 / 100
3764 ms31468 KiB
#include <stdio.h>

#define N	300000
#define Q	300000
#define N_	(1 << 19)	/* N_ = pow2(ceil(log2(Q))) */
#define INF	0x3f3f3f3f

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

unsigned int X = 12345;

int rand_() {
	return (X *= 3) >> 1;
}

int xx[N], gg[N], tt[N * 2 + Q], n;
int yy[Q], yy_[Q], q_;

int compare1(int h1, int h2) {
	int type1, type2;

	if (tt[h1] != tt[h2])
		return tt[h1] - tt[h2];
	type1 = h1 < n * 2 ? ((h1 & 1) == 0 ? 1 : -1) : 0;
	type2 = h2 < n * 2 ? ((h2 & 1) == 0 ? 1 : -1) : 0;
	return type2 - type1;
}

int compare2(int h1, int h2) {
	return yy[h1] - yy[h2];
}

int compare3(int i, int j) {
	return gg[i] != gg[j] ? gg[i] - gg[j] : xx[i] - xx[j];
}

int (*compare)(int, int);

void sort(int *hh, int l, int r) {
	while (l < r) {
		int i = l, j = l, k = r, h = hh[l + rand_() % (r - l)], tmp;

		while (j < k) {
			int c = compare(hh[j], h);

			if (c == 0)
				j++;
			else if (c < 0) {
				tmp = hh[i], hh[i] = hh[j], hh[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = hh[j], hh[j] = hh[k], hh[k] = tmp;
			}
		}
		sort(hh, l, i);
		l = k;
	}
}

int zz[1 + N], ll[1 + N], rr[1 + N], ii_[1 + N], u_, l_, r_;

int node(int i) {
	static int _ = 1;

	zz[_] = rand_();
	ii_[_] = i;
	return _++;
}

void split(int u, int i) {
	int c;

	if (u == 0) {
		u_ = l_ = r_ = 0;
		return;
	}
	c = xx[ii_[u]] != xx[i] ? xx[ii_[u]] - xx[i] : ii_[u] - i;
	if (c < 0) {
		split(rr[u], i);
		rr[u] = l_, l_ = u;
	} else if (c > 0) {
		split(ll[u], i);
		ll[u] = r_, r_ = u;
	} else {
		u_ = u, l_ = ll[u], r_ = rr[u];
		ll[u] = rr[u] = 0;
	}
}

int merge(int u, int v) {
	if (u == 0)
		return v;
	if (v == 0)
		return u;
	if (zz[u] < zz[v]) {
		rr[u] = merge(rr[u], v);
		return u;
	} else {
		ll[v] = merge(u, ll[v]);
		return v;
	}
}

int tr_update(int u, int i) {
	split(u, i);
	return merge(merge(l_, u_ == 0 ? node(i) : 0), r_);
}

int tr_query(int u, int x) {
	int d;

	d = INF;
	while (u)
		if (xx[ii_[u]] < x)
			d = min(d, x - xx[ii_[u]]), u = rr[u];
		else
			d = min(d, xx[ii_[u]] - x), u = ll[u];
	return d;
}

int search(int x) {
	int lower = -1, upper = q_;

	while (upper - lower > 1) {
		int h = (lower + upper) / 2;

		if (yy_[h] * 2 <= x)
			lower = h;
		else
			upper = h;
	}
	return lower;
}

int stmn[N_ * 2], stmx[N_ * 2], n_;

void build() {
	int i;

	n_ = 1;
	while (n_ < q_)
		n_ <<= 1;
	for (i = 1; i < n_ * 2; i++)
		stmn[i] = INF, stmx[i] = -INF;
}

void update(int l, int r, int x) {
	for (l += n_, r += n_; l <= r; l >>= 1, r >>= 1) {
		if ((l & 1) == 1)
			stmn[l] = min(stmn[l], x), stmx[l] = max(stmx[l], x), l++;
		if ((r & 1) == 0)
			stmn[r] = min(stmn[r], x), stmx[r] = max(stmx[r], x), r--;
	}
}

int query(int i) {
	int y, l, r;

	l = r = y = yy_[i];
	for (i += n_; i > 0; i >>= 1)
		l = min(l, stmn[i]), r = max(r, stmx[i]);
	return l == -INF || r == INF ? -1 : max(y - l, r - y);
}

int pp[N], qq[N];

void remove_(int i) {
	int p = pp[i], q = qq[i];

	if (p != -1)
		qq[p] = q;
	if (q != -1)
		pp[q] = p;
	if (p == -1 && q == -1)
		update(0, q_ - 1, INF), update(0, q_ - 1, -INF);
	else if (p == -1)
		update(0, search(xx[q] * 2), xx[q]);
	else if (q == -1)
		update(search(xx[p] * 2 - 1) + 1, q - 1, xx[p]);
	else {
		int l = search(xx[p] * 2 - 1) + 1, h = search(xx[p] + xx[q]), r = search(xx[q] * 2);

		update(l, h, xx[p]), update(h + 1, r, xx[q]);
	}
}

int main() {
	static int hh[N * 2 + Q], inv[Q], ii[N], tr[N], ll_[N], rr_[N], ans[Q];
	int k, g, h, i;

	scanf("%d%d%d", &n, &k, &q_);
	for (i = 0; i < n; i++)
		scanf("%d%d%d%d", &xx[i], &gg[i], &tt[i << 1 | 0], &tt[i << 1 | 1]), gg[i]--;
	for (h = 0; h < q_; h++)
		scanf("%d%d", &yy[h], &tt[n * 2 + h]);
	if (n <= 60000 && q_ <= 60000 && k <= 400) {
		for (h = 0; h < n * 2 + q_; h++)
			hh[h] = h;
		compare = compare1, sort(hh, 0, n * 2 + q_);
		for (h = 0; h < n * 2 + q_; h++) {
			int h_ = hh[h];

			if (h_ >= n * 2) {
				h_ -= n * 2;
				for (g = 0; g < k; g++)
					ans[h_] = max(ans[h_], tr_query(tr[g], yy[h_]));
				if (ans[h_] == INF)
					ans[h_] = -1;
			} else {
				i = h_ >> 1;
				tr[gg[i]] = tr_update(tr[gg[i]], i);
			}
		}
	} else {
		for (h = 0; h < q_; h++)
			hh[h] = h;
		compare = compare2, sort(hh, 0, q_);
		for (h = 0; h < q_; h++)
			yy_[h] = yy[hh[h]], inv[hh[h]] = h;
		for (i = 0; i < n; i++)
			ii[i] = i;
		compare = compare3, sort(ii, 0, n);
		pp[ii[0]] = -1, qq[ii[n - 1]] = -1;
		ll_[0] = 0, rr_[n - 1] = q_ - 1;
		for (h = 0; h + 1 < n; h++)
			if (gg[ii[h]] == gg[ii[h + 1]]) {
				int h_ = search(xx[ii[h]] + xx[ii[h + 1]]);

				qq[ii[h]] = ii[h + 1], pp[ii[h + 1]] = ii[h];
				rr_[h] = h_, ll_[h + 1] = h_ + 1;
			} else {
				qq[ii[h]] = -1, pp[ii[h + 1]] = -1;
				rr_[h] = q_ - 1, ll_[h + 1] = 0;
			}
		build();
		for (h = 0; h < n; h++)
			if (ll_[h] <= rr_[h])
				update(ll_[h], rr_[h], xx[ii[h]]);
		for (h = 0; h < n * 2 + q_; h++)
			hh[h] = h;
		compare = compare1, sort(hh, 0, n * 2 + q_);
		for (h = 0; h < n * 2 + q_; h++) {
			int h_ = hh[h];

			if (h_ >= n * 2) {
				h_ -= n * 2;
				ans[h_] = query(inv[h_]);
			} else if ((h_ & 1) == 1)
				remove_(h_ >> 1);
		}
	}
	for (h = 0; h < q_; h++)
		printf("%d\n", ans[h]);
	return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

new_home.c: In function 'main':
new_home.c:193:2: warning: ignoring return value of 'scanf', declared with attribute warn_unused_result [-Wunused-result]
  193 |  scanf("%d%d%d", &n, &k, &q_);
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
new_home.c:195:3: warning: ignoring return value of 'scanf', declared with attribute warn_unused_result [-Wunused-result]
  195 |   scanf("%d%d%d%d", &xx[i], &gg[i], &tt[i << 1 | 0], &tt[i << 1 | 1]), gg[i]--;
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
new_home.c:197:3: warning: ignoring return value of 'scanf', declared with attribute warn_unused_result [-Wunused-result]
  197 |   scanf("%d%d", &yy[h], &tt[n * 2 + h]);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...