Submission #838876

#TimeUsernameProblemLanguageResultExecution timeMemory
838876pavementMinerals (JOI19_minerals)C++17
40 / 100
32 ms2768 KiB
#include "minerals.h"
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mp make_pair

void Solve(int N) {
	vector<int> uniq, others;
	for (int i = 0, prv = 0; i < 2 * N; i++) {
		if (Query(i + 1) > prv) {
			uniq.pb(i);
			prv++;
		} else {
			others.pb(i);
		}
	}
	int cur_l = 0, cur_r = N - 1, prv = N;
	vector<int> lo(2 * N, 0), hi(2 * N, N - 1), mid(2 * N), ans(2 * N, -1);
	
	auto shift = [&](int new_l, int new_r) {
		int tmp_new_l = new_l, tmp_new_r = new_r;
		assert(cur_l <= cur_r);
		assert(new_l <= new_r);
		if (new_l < cur_l) {
			swap(cur_l, new_l);
			swap(cur_r, new_r);
		}
		// case 1: one range compeletely covers the other
		if (new_r <= cur_r) {
			for (int i = cur_l; i < new_l; i++) {
				prv = Query(uniq[i] + 1);
			}
			for (int i = new_r + 1; i <= cur_r; i++) {
				prv = Query(uniq[i] + 1);
			}
		} else if (cur_r < new_l) {
			// case 2: completely disjoint
			for (int i = cur_l; i <= cur_r; i++) {
				prv = Query(uniq[i] + 1);
			}
			for (int i = new_l; i <= new_r; i++) {
				prv = Query(uniq[i] + 1);
			}
		} else {
			// intersection
			for (int i = cur_l; i < new_l; i++) {
				prv = Query(uniq[i] + 1);
			}
			for (int i = cur_r + 1; i <= new_r; i++) {
				prv = Query(uniq[i] + 1);
			}
		}
		cur_l = tmp_new_l;
		cur_r = tmp_new_r;
	};
	
	for (int rep = 0; (1 << rep) <= N; rep++) {
		vector<bool> can(2 * N, 0);
		for (int i : others) if (lo[i] <= hi[i]) {
			mid[i] = (lo[i] + hi[i]) / 2;
			// insert [lo[i], mid[i]] from uniq
		}
		sort(others.begin(), others.end(), [&](const auto &lhs, const auto &rhs) {
			if (rep % 2 == 0) {
				return mid[lhs] > mid[rhs];
			} else {
				return mid[lhs] < mid[rhs];
			}
		});
		for (int i : others) if (lo[i] <= mid[i]) {
			shift(0, mid[i]);
			int ret_1 = Query(i + 1);
			if (ret_1 == prv) {
				can[i] = 1;
			}
			prv = ret_1;
		}
		for (int i : others) if (lo[i] <= mid[i]) {
			if (can[i]) {
				ans[i] = mid[i];
				hi[i] = mid[i] - 1;
			} else {
				lo[i] = mid[i] + 1;
			}
		}
	}
	for (int i : others) {
		Answer(i + 1, uniq[ans[i]] + 1);
	}
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...