이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |