This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include "books.h"
using namespace std;
//
// --- Sample implementation for the task books ---
//
// To compile this program with the sample grader, place:
// books.h books_sample.cpp sample_grader.cpp
// in a single folder and run:
// g++ books_sample.cpp sample_grader.cpp
// in this folder.
//
void subtask2(int N, int K, long long A, int S) {
vector<long long> a(N);
for (int i=0;i<N;i++) {
a[i] = skim(i+1);
}
long long pref = 0;
for (int i=0;i<K;i++) {
pref += a[i];
}
if (pref > 2*A) {
impossible();
return;
}
auto it = lower_bound(a.begin(), a.end(), A);
if (it != a.end()) {
long long num = *it;
for (int i=0;i<K-1;i++) num += a[i];
if (num <= 2LL*A) {
vector<int> idx;
for (int i=0;i<K-1;i++) idx.push_back(i+1);
idx.push_back(distance(a.begin(), it)+1);
answer(idx);
return;
}
}
while (a.back() >= A)a.pop_back();
for (int i=0;i<(int)a.size()-K+1;i++) {
long long sum = 0;
for (int j=0;j<K;j++) {
sum += a[j+i];
}
if (A <= sum && sum <= 2LL*A) {
vector<int> idx;
for (int j=0;j<K;j++) {
idx.push_back(i+j+1);
}
answer(idx);
return;
}
}
impossible();
}
vector<int> vals;
int toge;
int qu;
int query(int i) {
if (vals[i] == -1) {
qu++;
if (qu > toge) {
assert(false);
}
vals[i] = skim(i+1);
}
return vals[i];
}
void solve(int N, int K, long long A, int S) {
toge = S;
if (N <= S) {
subtask2(N,K,A,S);
}
vals.assign(N, -1);
// check first K values
long long sum = 0;
for (int i=0;i<K;i++) {
sum += query(i);
}
if (sum > 2*A) {
impossible();
return;
}
if (sum >= A) {
vector<int> idx;
for (int i=0;i<K;i++) {
idx.push_back(i+1);
}
answer(idx);
return;
}
// binary search for the first value greater or equal to A
int l = K, r = N-1;
int ans = -1;
long long valans = -1;
while (l <= r) {
int m = l + (r-l)/2;
long long val = query(m);
if (val == A) {
ans = m;
valans = A;
break;
}
if (val < A) {
l = m+1;
}
else {
ans = m;
valans = val;
r = m-1;
}
}
// check if prefix + a is fitting
int last = N-1;
if (ans != -1) {
long long cand = sum - query(K-1) + valans;
long long cand2 = sum - query(0) + valans;
if (A <= cand && cand <= 2*A) {
vector<int> idx;
for (int i=0;i<K-1;i++)idx.push_back(i+1);
idx.push_back(ans+1);
answer(idx);
return;
}
if (A <= cand2 && cand2 <= 2*A) {
vector<int> idx;
for (int i=1;i<K;i++)idx.push_back(i+1);
idx.push_back(ans+1);
answer(idx);
return;
}
last = ans-1;
}
long long suf = 0;
for (int i=0;i<K;i++) {
suf += query(last - i);
}
if (A <= suf && suf <= 2*A) {
vector<int> idx;
for (int i=0;i<K;i++) {
idx.push_back(last - i + 1);
}
answer(idx);
return;
}
if (suf < A) {
impossible();
return;
}
// now prefix has sum < a, and suffix has sum > 2*a
// then, there must be a subarray, such that the sum is exactly in between
// why? because if that wasn't true, then the added contribution must be greater than a
// however, since all elements are smaller than a, any difference between two elements cannot be greater
// that a, hence, there must be a subarray with the desired sum
l = 0, r = last - K + 1;
while (l <= r) {
int m = l + (r-l)/2;
long long tmpSum = 0;
for (int i=0;i<K;i++) {
tmpSum += query(i+m);
}
if (A <= tmpSum && tmpSum <= 2*A) {
vector<int> idx;
for (int i=0;i<K;i++)idx.push_back(i+m+1);
answer(idx);
return;
}
else if (tmpSum < A) {
l = m+1;
}
else {
r = m-1;
}
}
assert(false);
}
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |