# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
542923 | alextodoran | Dungeons Game (IOI21_dungeons) | 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.
/**
____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N_MAX = 400000;
const int N_BITS = 25;
const int S_QITS = 13;
int N;
int strength[N_MAX];
int winBonus[N_MAX];
int loseBonus[N_MAX];
int winEdge[N_MAX];
int loseEdge[N_MAX];
struct Jump {
int last;
ll bonus;
int maxDiff;
// maximum (bonus - strength) at some moment when we lost
};
Jump operator + (const Jump &j1, const Jump &j2) {
return Jump{j2.last, j1.bonus + j2.bonus, (int) min((ll) 0, max((ll) j1.maxDiff, j1.bonus + j2.maxDiff))};
}
Jump jump[N_MAX + 1][S_QITS][N_BITS];
void init (int _N, vector <int> _S, vector <int> _P, vector <int> _W, vector <int> _L) {
// Transfer input to global
N = _N;
for (int u = 0; u < N; u++) {
strength[u] = _S[u];
winBonus[u] = _S[u];
loseBonus[u] = _P[u];
winEdge[u] = _W[u];
loseEdge[u] = _L[u];
}
// Precompute jumps
for (int sqit = 0; sqit < S_QITS; sqit++) {
for (int nbit = 0; nbit < N_BITS; nbit++) {
jump[N][sqit][nbit] = Jump{N, 0, INT_MIN};
}
}
for (int u = 0; u < N; u++) {
for (int sqit = 0; sqit < S_QITS; sqit++) {
if ((1 << (sqit * 2)) > strength[u]) {
jump[u][sqit][0] = Jump{winEdge[u], winBonus[u], INT_MIN};
} else {
jump[u][sqit][0] = Jump{loseEdge[u], loseBonus[u], 0 - strength[u]};
}
}
}
for (int nbit = 1; nbit < N_BITS; nbit++) {
for (int u = 0; u < N; u++) {
for (int sqit = 0; sqit < S_QITS; sqit++) {
Jump j = jump[u][sqit][nbit - 1];
jump[u][sqit][nbit] = j + jump[j.last][sqit][nbit - 1];
}
}
}
}
ll simulate (int u, int initStrength) {
ll currStrength = initStrength;
while (true) {
for (int nbit = N_BITS - 1; nbit >= 0; nbit--) {
int sqit = 0;
while (sqit + 1 < S_QITS && (1 << ((sqit + 1) * 2)) <= currStrength) {
sqit++;
}
Jump j = jump[u][sqit][nbit];
if (u < N && currStrength + j.maxDiff < 0) {
u = j.last;
currStrength += j.bonus;
}
}
if (u == N) {
break;
}
if (currStrength >= strength[u]) {
currStrength += winBonus[u];
u = winEdge[u];
} else {
currStrength += loseBonus[u];
u = loseEdge[u];
}
}
return currStrength;
}