Submission #924876

#TimeUsernameProblemLanguageResultExecution timeMemory
924876Programmer123Dungeons Game (IOI21_dungeons)C++17
11 / 100
7154 ms1695008 KiB
#include "dungeons.h" #include <bits/stdc++.h> #define JUMP_SIZE 40 std::vector<int> s, p, w, l; int N; long long *minBlitz, *gainBlitz; int **jumpTo; __int128_t **jumpGain; bool identical = true; long long dp(int node, long long str); long long calc(int node, long long str) { if (str >= s[node]) { return dp(w[node], str + s[node]); } else return dp(l[node], str + p[node]); } std::unordered_map<long long, long long> *cache; long long dp(int node, long long str) { assert(node != N); if (str >= minBlitz[node]) return str + gainBlitz[node]; if (!cache[node].count(str)) { cache[node][str] = calc(node, str); } return cache[node][str]; } void init(int n, std::vector<int> _s, std::vector<int> _p, std::vector<int> _w, std::vector<int> _l) { N = n; s = std::move(_s); p = std::move(_p); w = std::move(_w); l = std::move(_l); for (int i = 1; i < N; ++i) { if (s[i] != s[0]) identical = false; } minBlitz = new long long[N + 1]; gainBlitz = new long long[N + 1]; for (int i = 0; i <= N; ++i) { gainBlitz[i] = -1; } std::function<void(int)> calc = [&](int x) { if (gainBlitz[x] != -1) return; if (x == N) { minBlitz[x] = 0; gainBlitz[x] = 0; return; } calc(w[x]); minBlitz[x] = std::max(minBlitz[w[x]] - s[x], (long long) s[x]); gainBlitz[x] = gainBlitz[w[x]] + s[x]; }; for (int i = 0; i <= N; ++i) { calc(i); } cache = new std::remove_pointer<decltype(cache)>::type[N + 1]; #ifdef LOCAL std::cout << "minBlitz:"; for (int i = 0; i <= N; ++i) { std::cout << " " << minBlitz[i]; } std::cout << std::endl; std::cout << "gainBlitz:"; for (int i = 0; i <= N; ++i) { std::cout << " " << gainBlitz[i]; } std::cout << std::endl; #endif jumpTo = new int *[N + 1]; jumpGain = new __int128_t *[N + 1]; for (int i = 0; i <= N; ++i) { jumpTo[i] = new int[JUMP_SIZE]; jumpGain[i] = new __int128_t[JUMP_SIZE]; } for (int i = 0; i < N; ++i) { jumpTo[i][0] = l[i]; jumpGain[i][0] = p[i]; } jumpTo[N][0] = N; jumpGain[N][0] = 0; for (int i = 1; i < JUMP_SIZE; ++i) { for (int j = 0; j <= N; ++j) { jumpTo[j][i] = jumpTo[jumpTo[j][i - 1]][i - 1]; jumpGain[j][i] = jumpGain[j][i - 1] + jumpGain[jumpTo[j][i - 1]][i - 1]; } } } long long simulate(int x, int _z) { __int128_t z = _z; if (identical) { if (z >= s[0]) return z + gainBlitz[x]; for (int i = JUMP_SIZE - 1; i >= 0; --i) { if (z + jumpGain[x][i] <= s[0]) { z += jumpGain[x][i]; x = jumpTo[x][i]; } } while (z < s[0]) { z += p[x]; x = l[x]; } return z + gainBlitz[x]; } return dp(x, 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...