제출 #1184799

#제출 시각아이디문제언어결과실행 시간메모리
1184799steveonalexColors (BOI20_colors)C++20
67 / 100
0 ms436 KiB
#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 c; bool valid; int query(ll x){ if (S.insert(x).second == false){ valid = false; } ll diff = abs(last - x); last = x; return diff >= c; } int grade(){ ll n = rngesus(1, 1e18); 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){ 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 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...