This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
//Challenge: Accepted
#include "dungeons.h"
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <assert.h>
using namespace std;
void debug(){cout << endl;}
template<class T, class ... U> void debug(T a, U ... b){cout << a << " ", debug(b...);}
template<class T> void pary(T l, T r) {
while (l != r) cout << *l << " ", l++;
cout << endl;
}
#define ll long long
#define maxn 400005
#define pii pair<int, int>
#define ff first
#define ss second
#define io ios_base::sync_with_stdio(0);cin.tie(0);
int n;
vector<int> s, p, w, l, disp;
struct WIN{
int anc[19][maxn];
ll ma[19][maxn];
ll sum[19][maxn];
void build() {
for (int i = 0;i < n;i++) {
anc[0][i] = w[i];
ma[0][i] = s[i];
sum[0][i] = s[i];
}
anc[0][n] = n;
for (int i = 1;i < 19;i++) {
for (int j = 0;j <= n;j++) {
anc[i][j] = anc[i-1][anc[i-1][j]];
sum[i][j] = sum[i-1][j] + sum[i-1][anc[i-1][j]];
ma[i][j] = max(ma[i-1][j], ma[i-1][anc[i-1][j]] - sum[i-1][j]);
}
}
}
void move(int &x, ll &val) { //brings it to the nearest loss
for (int i = 18;i >= 0;i--) {
if (val >= ma[i][x]) {
val += sum[i][x];
x = anc[i][x];
}
}
}
} win;
const int inf = 1<<26;
struct LOSE{
int anc[16][maxn];
int mi[16][maxn];
int sum[16][maxn];
void build(int bit) {
for (int i = 0;i < n;i++) {
if (s[i] >= (1<<bit)) mi[0][i] = s[i];
else mi[0][i] = 1<<(bit+2);
if (s[i] < (1<<bit)) sum[0][i] = s[i], anc[0][i] = w[i];
else sum[0][i] = p[i], anc[0][i] = l[i];
}
anc[0][n] = n;
for (int i = 1;i < 16;i++) {
for (int j = 0;j <= n;j++) {
anc[i][j] = anc[i-1][anc[i-1][anc[i-1][j]]];
sum[i][j] = min(inf, sum[i-1][j] + sum[i-1][anc[i-1][j]] + sum[i-1][anc[i-1][anc[i-1][j]]]);
mi[i][j] = max(0, min(mi[i-1][j], min(mi[i-1][anc[i-1][j]] - sum[i-1][j], mi[i-1][anc[i-1][anc[i-1][j]]] - sum[i-1][j] - sum[i-1][anc[i-1][j]])));
}
}
}
void move(int &x, ll &val) { //brings it to the nearest win
for (int i = 15;i >= 0;i--) {
if (val < mi[i][x]) {
val += sum[i][x];
x = anc[i][x];
}
if (val < mi[i][x]) {
val += sum[i][x];
x = anc[i][x];
}
}
}
} lose[13];
void init(int nv, vector<int> sv, vector<int> pv, vector<int> wv, vector<int> lv) {
n = nv;
s = sv, p = pv, w = wv, l = lv;
win.build();
for (int i = 0;i < 13;i++) lose[i].build(i*2);
//lose.build();
}
long long simulate(int x, int z) {
ll ans = z;
for (int i = 0;i < 13 && x != n;i++) {
for (int j = 0;j < 4;j++) {
lose[i].move(x, ans);
if (x != n && ans >= s[x]) {
ans += s[x];
x = w[x];
}
}
win.move(x, ans);
}
return ans;
}
/*
3 2
2 6 9
3 1 2
2 2 3
1 0 1
0 1
2 3
3 3
14 14 14
2 1 1
1 2 3
1 2 0
0 0
2 4
1 1
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |