제출 #1065529

#제출 시각아이디문제언어결과실행 시간메모리
1065529j_vdd16던전 (IOI21_dungeons)C++17
50 / 100
7056 ms415344 KiB
#include "dungeons.h" #include <algorithm> #include <bitset> #include <cstdint> #include <cstring> #include <iostream> #include <limits.h> #include <math.h> #include <map> #include <numeric> #include <queue> #include <set> #include <stack> #include <string> #include <vector> //#define int long long #define ll long long #define loop(X, N) for(int X = 0; X < (N); X++) #define all(V) V.begin(), V.end() #define rall(V) V.rbegin(), V.rend() using namespace std; typedef vector<int> vi; typedef vector<vi> vvi; typedef pair<int, int> ii; typedef vector<ii> vii; typedef vector<vector<ii>> vvii; typedef vector<bool> vb; typedef vector<vector<bool>> vvb; typedef uint64_t u64; typedef int64_t i64; int n; constexpr int POW = 24; vi liftLoss[POW], liftWin[POW]; vector<pair<ll, ll>> maxLossValues[POW], minWinValues[POW]; vector<ll> s, p; vi w, l; vector<pair<ll, ll>> minToEscape; void init(int _n, std::vector<int> _s, std::vector<int> _p, std::vector<int> _w, std::vector<int> _l) { n = _n; w = _w; l = _l; w.push_back(n); l.push_back(n); //set<ll> strengths; for (int x : _s) { s.push_back(x); //strengths.insert(x); } for (int x : _p) p.push_back(x); s.push_back(0); p.push_back(0); minToEscape = vector<pair<ll, ll>>(n + 1); for (int i = n - 1; i >= 0; i--) { auto [nextMin, nextGain] = minToEscape[w[i]]; if (s[i] * 2 >= nextMin) { minToEscape[i].first = s[i]; } else { minToEscape[i].first = nextMin - s[i]; } minToEscape[i].second = nextGain + s[i]; } maxLossValues[0] = vector<pair<ll, ll>>(n + 1); minWinValues[0] = vector<pair<ll, ll>>(n + 1); liftLoss[0] = vi(n + 1); liftWin[0] = vi(n + 1); loop(i, n + 1) { liftLoss[0][i] = l[i]; maxLossValues[0][i] = { p[i], s[i] }; liftWin[0][i] = w[i]; minWinValues[0][i] = { s[i], s[i] }; } for (int pow = 1; pow < POW; pow++) { maxLossValues[pow] = vector<pair<ll, ll>>(n + 1); minWinValues[pow] = vector<pair<ll, ll>>(n + 1); liftLoss[pow] = vi(n + 1); liftWin[pow] = vi(n + 1); loop(i, n + 1) { { auto [gain, maxValue] = maxLossValues[pow - 1][i]; int next = liftLoss[pow - 1][i]; liftLoss[pow][i] = liftLoss[pow - 1][next]; auto [nextGain, nextMaxValue] = maxLossValues[pow - 1][next]; maxLossValues[pow][i].first = gain + nextGain; maxLossValues[pow][i].second = min(maxValue, nextMaxValue - gain); } { auto [gain, minValue] = minWinValues[pow - 1][i]; int next = liftWin[pow - 1][i]; liftWin[pow][i] = liftWin[pow - 1][next]; auto [nextGain, nextMinValue] = minWinValues[pow - 1][next]; minWinValues[pow][i].first = gain + nextGain; minWinValues[pow][i].second = max(minValue, nextMinValue - gain); } } } return; } long long simulate(int x, int _z) { ll z = _z; while (x != n) { for (int pow = POW - 1; pow >= 0; pow--) { if (z < maxLossValues[pow][x].second) { z += maxLossValues[pow][x].first; x = liftLoss[pow][x]; } } for (int pow = POW - 1; pow >= 0; pow--) { if (z >= minWinValues[pow][x].second) { z += minWinValues[pow][x].first; x = liftWin[pow][x]; } } if (x == n) break; if (z >= minToEscape[x].first) { z += minToEscape[x].second; x = n; break; } //z += s[x]; //x = w[x]; } // while (x != n) { // if (z >= minToEscape[x].first) { // z += minToEscape[x].second; // x = n; // break; // } // if (z >= s[x]) { // z += s[x]; // x = w[x]; // } // else { // z += p[x]; // x = l[x]; // } // } return z; }
#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...