#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MASK(i) (1ULL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
#define ALL(v) (v).begin(), (v).end()
ll max(ll a, ll b){return (a > b) ? a : b;}
ll min(ll a, ll b){return (a < b) ? a : b;}
ll gcd(ll a, ll b){return __gcd(abs(a), abs(b));}
ll lcm(ll a, ll b){return abs(a) / gcd(a, b) * abs(b);}
ll LASTBIT(ll mask){return (mask) & (-mask);}
int pop_cnt(ull mask){return __builtin_popcountll(mask);}
int ctz(ull mask){return __builtin_ctzll(mask);}
int logOf(ull mask){return 63 - __builtin_clzll(mask);}
// mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
mt19937_64 rng(1);
ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);}
template <class T1, class T2>
bool maximize(T1 &a, T2 b){
if (a < b) {a = b; return true;}
return false;
}
template <class T1, class T2>
bool minimize(T1 &a, T2 b){
if (a > b) {a = b; return true;}
return false;
}
template <class T>
void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){
for(auto item: container) out << item << separator;
out << finish;
}
template <class T>
void remove_dup(vector<T> &a){
sort(ALL(a));
a.resize(unique(ALL(a)) - a.begin());
}
ll solve(ll n);
namespace InteractorLib{
set<ll> S;
ll last = 0;
ll n, c;
bool valid;
int query(ll x){
if (x < 1 || x > n) valid = false;
if (S.insert(x).second == false){
valid = false;
}
ll diff = abs(last - x);
last = x;
return diff >= c;
}
int grade(){
n = rngesus(666532744850833408LL, 666532744850833408LL);
c = rngesus(max(1, n - 100), n);
cout << n << " " << c << "\n";
S.clear(); last = 0;
valid = true;
ll ans = solve(n);
if (valid == false) return 1;
if (ans != c) return 2;
if (S.size() > 64) return 3;
return 0;
}
};
// using namespace InteractorLib;
int query(ll x){
if (x < 1) exit(1);
cout << "? " << x << endl;
int verdict; cin >> verdict;
return verdict;
}
void update(pair<ll, ll> &p, ll x, bool verdict){
if (verdict) minimize(p.second, x);
else maximize(p.first, x + 1);
}
namespace Sub3{
int solve(ll n){
pair<ll, ll> ans = make_pair(1, n);
ll last = n / 2 + 1;
query(last);
ll l = last, r = last;
while(r - l + 1 < n){
l = max(1, l - 32);
int verdict = query(l);
update(ans, abs(last - l), verdict);
last = l;
if (verdict) break;
if (r - l + 1 == n) break;
r = min(n, r + 32);
verdict = query(r);
update(ans, abs(last - r), verdict);
last = r;
if (verdict) break;
}
while(l <= r){
if (ans.first == ans.second) break;
if (last == l){
r--;
int verdict = query(r);
update(ans, abs(last - r), verdict);
last = r;
}
else{
l++;
int verdict = query(l);
update(ans, abs(last - l), verdict);
last = l;
}
}
return ans.first;
}
}
namespace Sub4{
ll get_starting_point(ll n){
pair<ll, ll> range = {0, 0};
ll cur = 0;
ll l = 1;
while(l < n){
ll mid = (l + n) >> 1;
if (cur == range.first) cur += mid;
else cur -= mid;
minimize(range.first, cur);
maximize(range.second, cur);
l = mid + 1;
}
if (range.second - range.first + 1 != n) assert(false);
return 1 - range.first;
}
ll solve(ll n){
pair<ll, ll> ans = make_pair(1, n);
ll last = get_starting_point(n);
query(last);
set<ll> S;
while(ans.first < ans.second){
ll mid = (ans.first + ans.second) / 2;
ll query_point = -1;
while(query_point == -1 && mid >= ans.first){
if (last + mid <= n && S.find(last + mid) == S.end()) query_point = last + mid;
else if (last - mid >= 1 && S.find(last - mid) == S.end()) query_point = last - mid;
if (query_point != -1) break;
mid--;
}
if (query_point == -1) break;
int verdict = query(query_point);
update(ans, abs(query_point - last), verdict);
last = query_point;
S.insert(last);
}
if (ans.first == ans.second) return ans.first;
if (ans.second == ans.first + 1) {
if (last - ans.first > 1 && S.find(last - ans.first) == S.end()){
int verdict = query(last - ans.first);
update(ans, ans.first, verdict);
return ans.first;
}
if (last + ans.first <= n && S.find(last + ans.first) == S.end()){
int verdict = query(last + ans.first);
update(ans, ans.first, verdict);
return ans.first;
}
for(int i = 1; i + ans.first <= n; ++i) {
if (S.find(i) == S.end() && S.find(i + ans.first) == S.end()){
query(i);
int verdict = query(i + ans.first);
update(ans, ans.first, verdict);
return ans.first;
}
}
}
if (ans.first + 1 < ans.second){
for(ll i = 1; i + ans.first <= n; ++i){
ll l = i, r = i + ans.first;
bool check = true;
ll last = -1;
while(true){
if (l < 1 || S.find(l) != S.end()){
check = false;
break;
}
if (last != -1 && abs(last - l) + 1 == ans.second) break;
last = l;
l--;
if (r > n || S.find(r) != S.end()){
check = false;
break;
}
if (abs(last - r) + 1 == ans.second) break;
last = r;
r++;
}
if (check == false) continue;
l = i, r = i + ans.first;
last = -1;
while(ans.first < ans.second){
int verdict = query(l);
if (last != -1) update(ans, abs(last - l), verdict);
if (last != -1 && abs(last - l) + 1 >= ans.second) break;
last = l;
l--;
verdict = query(r);
update(ans, abs(last - r), verdict);
if (abs(last - r) + 1 >= ans.second) break;
last = r;
r++;
}
break;
}
}
return ans.first;
}
}
ll solve(ll n){
if (n <= 1000) return Sub3::solve(n);
return Sub4::solve(n);
}
int main(void){
ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
clock_t start = clock();
// for(int t = 1; t <= 1000; ++t) {
// cout << "Test case: " << t << endl;
// int code = grade();
// if (code == 0) {
// cout << "Correct!" << endl;
// }
// else{
// cout << "Incorrect[" << code << "]!" << endl;
// break;
// }
// }
ll n; cin >> n;
int ans = solve(n);
cout << "= " << ans << endl;
cerr << "Time elapsed: " << clock() - start << "ms!\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |