# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1064259 | crafticat | From Hacks to Snitches (BOI21_watchmen) | C++17 | 0 ms | 0 KiB |
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>
using namespace std;
#include <bits/stdc++.h>
#include <utility>
using namespace std;
using ll = __int128;
using pi = pair<ll,ll>;
using pl = pair<ll,ll>;
#define temp(T) template<class T>
temp(T) using V = vector<T>;
using vi = V<ll>;
using vl = V<ll>;
using vvi = V<vi>;
using vpi = V<pi>;
using vb = V<bool>;
using vvb = V<vb>;
vi dx = {0,1,-1,0};
vi dy = {1,0,0,-1};
#define sz(x) x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define sor(x) sort(all(x))
#define rsz resize
#define ins insert
#define pb push_back
#define eb emplace_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define FOR(i,a,b) for (ll i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (ll i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define rep(a) F0R(_,a)
#define each(a,x) for (auto& a: x)
using str = string;
const ll MOD = 1e9 + 7;
const ll BIG = 1e18;
const ll INF = 1e9 + 2;
temp(T) bool ckmin(T& a, const T& b) {
return b < a ? a = b, 1 : 0; } // set a = min(a,b)
temp(T) bool ckmax(T& a, const T& b) {
return a < b ? a = b, 1 : 0; } // set a = max(a,b)
void unsyncIO() { cin.tie(0)->sync_with_stdio(0); }
// FILE I/O
void setIn(str s) { freopen(s.c_str(),"r",stdin); }
void setOut(str s) { freopen(s.c_str(),"w",stdout); }
void setIO(str s = "") {
unsyncIO();
if (sz(s)) setIn(s+".in"), setOut(s+".out"); // for USACO
}
#define read(x) ll x; cin >> x
temp(T) void pr(T x) {
cout << to_string(x);
}
temp(T) void prln(T x) {
cout << to_string(x) << "\n";
}
ll rand(ll a, ll b) {
return a + rand() % (b - a + 1);
}
#define gen(x,a,b) ll x = rand(a,b)
temp(T) void moveAll(V<T> &a, V<T> &b) {
each(x,b) {
a.pb(x);
}
b.clear();
}
vi genArr(ll n, ll a, ll b) {
vi generated(n);
F0R(i,n) {
generated[i] = rand(a,b);
}
return generated;
}
vvi genTree(ll n) {
vvi g(n + 1);
F0R(i,n) {
gen(p,0,i);
g[p].pb(i + 1);
g[i + 1].pb(p);
}
return g;
}
vvb readGrid(ll a, ll b) {
vvb grid(a + 2, vb(b + 2, true));
F0R(i, a) {
F0R(j, b) {
bool k; cin >> k;
grid[i + 1][j + 1] = k;
}
}
return grid;
}
int used;
map<int, ll> cash2;
long long skim(int);
__int128 skim2(int x) {
if (cash2.count(x)) return cash2[x];
used--;
if (used == 0) exit(5);
cash2[x] = skim(x);
return cash2[x];
}
void answer(std::vector<int>);
void impossible();
ll N2;
ll lowerbound(ll a) {
ll l = 1, r = N2; // false, false, true
while (r > l) {
ll mid = l + (r - l) / 2;
if (skim2(mid) >= a) {
r = mid;
} else
l = mid + 1;
}
if (skim2(l) < a && l == N2) return N2 + 1;
return l;
}
void solve(int n, int k, long long A, int usable) {
cash2.clear();
used = usable;
N2 = n;
ll next = lowerbound(A);
V<int> down, up;
ll sum = 0;
ll iter = 1;
if (next + 1 >= k) {
FOR(i,1, k + 1) {
up.pb(next - i);
sum += skim2(next - i);
}
}
while (sum > A * 2 && !up.empty()) {
ll diff = -skim2(up.back()) + skim2(iter);
sum += diff;
up.pop_back();
down.pb(iter++);
}
if (sum >= A && sum <= 2 * A) {
down.insert(down.end(),all(up));
answer(down);
return;
}
iter = 1;
sum = 0;
up.clear();
down.clear();
if (next > N2) {
impossible();
return;
}
while (sz(down) < k - 1) {
sum += skim2(iter);
down.pb(iter++);
}
if (sz(down) == k) {
sum -= skim2(down.back());
down.pop_back();
}
sum += skim2(next);
down.pb(next);
if (sum >= A && sum <= 2 * A) {
answer(down);
return;
}
impossible();
}
#if DEBUG
typedef long long ll;
void __attribute__((noreturn)) __attribute__((format(prllf, 1, 2))) result(const char *msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
fprintf(stderr, "\n");
va_end(args);
exit(0);
}
ll N, K, S, sUsed;
long long A;
vector<long long> seq;
void impossible() {
result("Impossible (not checked): %d book(s) skimmed", sUsed);
exit(0);
}
long long skim(int pos) {
printf("skim2(%d): ", pos);
if (pos < 1 || pos > N)
result("Invalid skim2");
printf("%lld\n", seq[pos]);
sUsed++;
if (sUsed > S) result("Out of books to skim2");
return seq[pos];
}
void answer(vector<int> v) {
printf("answer({");
for (ll i = 0; i < (ll) v.size(); ++i) {
printf("%d", v[i]);
if (i + 1 != (ll) v.size()) printf(", ");
}
printf("})\n");
if ((ll) v.size() != K) result("Invalid answer");
ll sum = 0;
for (auto x: v) {
if (x < 1 || x > N) result("Invalid answer");
sum += seq[x];
}
if (sum < A || 2 * A < sum) result("Wrong answer");
result("Correct: %d book(s) skimmed", sUsed);
exit(0);
}
int main() {
if (scanf("%d %d %lld %d", &N, &K, &A, &S) != 4)
result("Invalid input");
seq.resize(N + 1);
for (ll i = 1; i <= N; ++i) {
if (scanf("%lld", &(seq[i])) != 1) result("Invalid input");
if (i > 1 && seq[i] <= seq[i - 1]) result("Invalid input");
}
solve(N, K, A, S);
result("No answer");
}
#endif