Submission #541183

#TimeUsernameProblemLanguageResultExecution timeMemory
541183skittles1412Colors (BOI20_colors)C++17
43 / 100
522 ms424 KiB
#include "bits/extc++.h"

using namespace std;

template <typename T>
void dbgh(const T& t) {
	cerr << t << endl;
}

template <typename T, typename... U>
void dbgh(const T& t, const U&... u) {
	cerr << t << " | ";
	dbgh(u...);
}

#ifdef DEBUG
#define dbg(...)                                           \
	cerr << "L" << __LINE__ << " [" << #__VA_ARGS__ << "]" \
		 << ": ";                                          \
	dbgh(__VA_ARGS__)
#else
#define cerr   \
	if (false) \
	cerr
#define dbg(...)
#endif

#define endl "\n"
#define long int64_t
#define sz(x) int((x).size())

namespace s1 {

void solve(int n) {
	vector<int> vals;
	for (int i = 1; i <= n; i += 32) {
		vals.push_back(i);
	}
	vector<int> ord;
	int l = 0, r = sz(vals);
	while (l < r) {
		ord.push_back(vals[l++]);
		if (l < r) {
			ord.push_back(vals[--r]);
		}
	}
	reverse(begin(ord), end(ord));
	for (auto& a : ord) {
		cout << "? " << a << endl;
	}
	int _;
	cin >> _;
	int up = 0;
	for (int i = 0; i < sz(ord) - 1; i++) {
		int x;
		cin >> x;
		if (!x) {
			up = abs(ord[i + 1] - ord[i]);
		}
	}
	int prev = 1;
	bool b = true;
	for (int i = min(n - 1, up + 31); i > up; i--) {
		if (b) {
			prev += i;
		} else {
			prev -= i;
		}
		b ^= true;
		cout << "? " << prev << endl;
		int x;
		cin >> x;
		if (!x) {
			cout << "= " << i + 1 << endl;
			return;
		}
	}
	cout << "= " << up + 1 << endl;
}

}

long n;
set<long> vis;

bool valid(long x) {
	return 1 <= x && x <= n && !vis.count(x);
}

long mmid() {
	long lg = __lg(n);
	if ((1 << lg) == n) {
		return (1 + n) / 2;
	}
	return n - (1 << lg);
}

long dfs(long l, long r) {
	if (l == r) {
		return 1;
	}
	long mid = (l + r) / 2;
	long x = dfs(mid + 1, r);
	if (valid(x - mid)) {
		return x - mid;
	} else {
		return x + mid;
	}
}

long query(long x) {
	dbg(x);
	assert(valid(x));
	vis.insert(x);
	cout << "? " << x << endl;
	cin >> x;
	return x;
}

bool check(long l, long r, long prev, long val) {
	if (l == r) {
		return true;
	}
	long mid = (l + r) / 2;
	long nxt = prev + mid;
	if (!valid(nxt)) {
		nxt = prev - mid;
		if (!valid(nxt)) {
			return false;
		}
	}
	vis.insert(nxt);
	bool ans;
	if (val <= abs(nxt - prev)) {
		ans = check(l, mid, nxt, val);
	} else {
		ans = check(mid + 1, r, nxt, val);
	}
	vis.erase(nxt);
	return ans;
}

bool check(long start) {
	static mt19937 cowng(chrono::steady_clock::now().time_since_epoch().count());
	vis.clear();
	vis.insert(start);
	for (int i = 0; i < 10000; i++) {
		long x = cowng() % n + 1;
		if (!check(1, n, start, x)) {
			return false;
		}
	}
	return true;
}

void solve(long l, long r, long prev) {
	if (l == r) {
		cout << "= " << l << endl;
		return;
	}
	long mid = (l + r) / 2;
	long nxt = prev + mid;
	if (!valid(nxt)) {
		nxt = prev - mid;
	}
	if (query(nxt)) {
		solve(l, mid, nxt);
	} else {
		solve(mid + 1, r, nxt);
	}
}

void solve() {
	cin >> n;
	if (n <= 1000) {
		s1::solve(n);
		return;
	}
	long start = dfs(1, n);
	for (long i = max(long(1), start - 100); i <= min(n, start + 100); i++) {
		if (check(i)) {
			dbg(i);
			vis.clear();
			query(start);
			solve(1, n, start);
			return;
		}
	}
	assert(false);
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.exceptions(ios::failbit);
	solve();
}
#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...