제출 #794652

#제출 시각아이디문제언어결과실행 시간메모리
794652Johann던전 (IOI21_dungeons)C++17
100 / 100
2971 ms1014660 KiB
#include "dungeons.h" #include "bits/stdc++.h" using namespace std; typedef long long ll; typedef pair<ll, ll> pii; typedef vector<ll> vi; typedef vector<pii> vpii; typedef vector<vpii> vvpii; typedef vector<vvpii> vvvpii; #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() int N; const ll INF = 1LL << 60; vi S, P; vi Svalues; vector<int> W, L; vi dpWin; struct info { int node; ll gain; ll needed; }; typedef vector<info> vinf; typedef vector<vinf> vvinf; typedef vector<vvinf> vvvinf; vvvinf lifts; void init(int n, std::vector<int> s, std::vector<int> p, std::vector<int> w, std::vector<int> l) { N = n; S.resize(N), P.resize(N); W = w, L = l; for (int i = 0; i < N; ++i) S[i] = s[i], P[i] = p[i]; int maxi = *max_element(all(S)); Svalues.push_back(1); while (Svalues.back() <= maxi) Svalues.push_back(Svalues.back() * 8); dpWin.assign(N + 1, INF); dpWin[N] = 0; for (int i = N - 1; i >= 0; --i) dpWin[i] = S[i] + dpWin[W[i]]; lifts.resize(sz(Svalues) - 1); // assuming having reached Svalues[i] but not Svalues[i + 1] for (int ii = 0; ii < sz(lifts); ++ii) { // potentially to small for a good lift lifts[ii] = vvinf(N, vinf(ceil(log2(Svalues[ii]) + 1))); for (int i = 0; i < N; ++i) if (S[i] >= Svalues[ii]) lifts[ii][i][0] = {L[i], P[i], min(Svalues[ii + 1], S[i])}; else lifts[ii][i][0] = {W[i], S[i], Svalues[ii + 1]}; for (int j = 1; j < sz(lifts[ii].back()); ++j) for (int i = 0; i < N; ++i) { int mid = lifts[ii][i][j - 1].node; if (mid == N) lifts[ii][i][j] = lifts[ii][i][j - 1]; else lifts[ii][i][j] = {lifts[ii][mid][j - 1].node, lifts[ii][mid][j - 1].gain + lifts[ii][i][j - 1].gain, min(lifts[ii][i][j - 1].needed, lifts[ii][mid][j - 1].needed - lifts[ii][i][j - 1].gain)}; } } return; } void step(int &node, ll &z) { if (S[node] > z) { z += P[node]; node = L[node]; } else { z += S[node]; node = W[node]; } } long long simulate(int x, int z) { ll ans = z; int ii = 0; while (ii < sz(lifts) && x != N) { if (ans >= Svalues[ii + 1]) ++ii; else { assert(ans >= Svalues[ii]); for (int j = sz(lifts[ii][x]) - 1; j >= 0 && x != N; --j) { if (lifts[ii][x][j].needed > ans) { ans += lifts[ii][x][j].gain; x = lifts[ii][x][j].node; } } if (x != N) step(x, ans); } } return ans + dpWin[x]; }
#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...