제출 #542919

#제출 시각아이디문제언어결과실행 시간메모리
542919alextodoran던전 (IOI21_dungeons)C++17
63 / 100
1578 ms386968 KiB
/**
 ____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N_MAX = 50000;
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;
    ll 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, max(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, LLONG_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], LLONG_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;
}
#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...