Submission #828091

#TimeUsernameProblemLanguageResultExecution timeMemory
828091tranxuanbachThe Big Prize (IOI17_prize)C++17
90 / 100
74 ms9400 KiB
#include "prize.h" #include <bits/stdc++.h> using namespace std; const int N = 2e5 + 5; struct fenwick_tree{ int fen[N]; bool account[N]; void update(int i){ account[i] = true; i++; for (; i < N; i += i & -i){ fen[i]++; } } int query(int i){ i++; int ans = 0; for (; i > 0; i -= i & -i){ ans += fen[i]; } return ans; } int query(int l, int r){ return query(r) - query(l - 1); } } fen; int n; vector <int> query_answer[N]; int cnt_left[N], cnt_right[N]; int type[N]; void query(int x){ if (not query_answer[x].empty()){ return; } query_answer[x] = ask(x); cnt_left[x] = query_answer[x].front(); cnt_right[x] = query_answer[x].back(); type[x] = accumulate(query_answer[x].begin(), query_answer[x].end(), 0); } int find_min_lollipop(){ int lo = 1, hi = n - 1; while (lo < hi){ int mid = (lo + hi) >> 1; int sum = 0, t = mid; while (t){ sum += t; t = sqrt(t - 1); } if (sum >= n){ hi = mid; } else{ lo = mid + 1; } } return lo; } int type_lollipop; int jump_right[N]; int global_hi; int search_important(int l, int r){ if (l > r){ exit(0); } if (l == r){ query(l); fen.update(l); return l; } int mid = (l + r) >> 1; query(mid); if (type[mid] == type_lollipop){ if (fen.query(mid + 1, n - 1) != cnt_right[mid]){ return search_important(mid + 1, r); } else{ global_hi = min(global_hi, mid - 1); return search_important(l, mid - 1); } return -1; } if (not fen.account[mid]){ fen.update(mid); return mid; } int &idx = jump_right[mid]; while (idx < n){ query(idx); if (type[idx] == type_lollipop){ break; } if (not fen.account[idx]){ fen.update(idx); return idx; } idx++; } if (idx < n and fen.query(idx + 1, n - 1) != cnt_right[idx]){ return search_important(idx + 1, r); } else{ global_hi = min(global_hi, mid - 1); return search_important(l, mid - 1); } return -1; } int find_best(int _n){ n = _n; int min_lollipop = find_min_lollipop(); int max_important = n - min_lollipop; int lim = min(n, max_important + 1); for (int i = 0; i < lim; i++){ query(i); if (type[i] == 0){ return i; } } type_lollipop = *max_element(type, type + lim); for (int i = 0; i < lim; i++){ if (type[i] != type_lollipop){ fen.update(i); } } iota(jump_right, jump_right + n, 1); global_hi = n - 1; while (true){ int idx = search_important(lim, global_hi); if (type[idx] == 0){ return idx; } } return -1; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...