제출 #598313

#제출 시각아이디문제언어결과실행 시간메모리
598313KoD던전 (IOI21_dungeons)C++17
100 / 100
2858 ms2061128 KiB
#include "dungeons.h" #include <bits/stdc++.h> using ll = long long; using std::vector; struct dungeon { int s, p, w, l; }; struct info { int pos, thres; ll sum; info() = default; }; constexpr int LOG = 24; int size; vector<dungeon> data; vector<info> lift[LOG][LOG]; vector<info> win_all[LOG]; void init(int n, vector<int> s, vector<int> p, vector<int> w, vector<int> l) { size = n; data.reserve(n); for (int i = 0; i < n; ++i) { data.push_back({s[i], p[i], w[i], l[i]}); } for (int stage = 0; stage < LOG; ++stage) { lift[stage][0].resize(n + 1); const int lb = 1 << stage; const int ub = 1 << (stage + 1); for (int i = 0; i < n; ++i) { if (s[i] < lb) { lift[stage][0][i] = {w[i], std::max(0, ub - s[i]), s[i]}; } else if (s[i] >= ub) { lift[stage][0][i] = {l[i], std::max(0, ub - p[i]), p[i]}; } else { lift[stage][0][i] = {l[i], std::max(0, std::min(s[i], ub - p[i])), p[i]}; } } lift[stage][0][n] = {n, 0, 0}; for (int k = 0; k < stage; ++k) { lift[stage][k + 1].resize(n + 1); for (int i = 0; i <= n; ++i) { const auto [p0, t0, s0] = lift[stage][k][i]; const auto [p1, t1, s1] = lift[stage][k][p0]; lift[stage][k + 1][i] = {p1, s0 >= t1 ? 0 : std::min<int>(t0, t1 - s0), s0 + s1}; } } } win_all[0].resize(n + 1); for (int i = 0; i < n; ++i) { win_all[0][i] = {w[i], 0, s[i]}; } win_all[0][n] = {n, 0, 0}; for (int k = 0; k < LOG - 1; ++k) { win_all[k + 1].resize(n + 1); for (int i = 0; i <= n; ++i) { const auto [p0, t0, s0] = win_all[k][i]; const auto [p1, t1, s1] = win_all[k][p0]; win_all[k + 1][i] = {p1, 0, s0 + s1}; } } } ll simulate(int x, int z) { int stage = 0; while (true) { while (z >= (1 << (stage + 1))) { stage += 1; } if (x == size) { return z; } if (stage >= LOG) { break; } for (int k = stage; k >= 0; --k) { if (lift[stage][k][x].pos != size and z < lift[stage][k][x].thres) { z += lift[stage][k][x].sum; x = lift[stage][k][x].pos; } } if (z >= data[x].s) { z += data[x].s; x = data[x].w; } else { z += data[x].p; x = data[x].l; } } ll ret = z; for (int k = LOG - 1; k >= 0; --k) { if (win_all[k][x].pos != size) { ret += win_all[k][x].sum; x = win_all[k][x].pos; } } ret += data[x].s; return ret; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...