Submission #1339600

#TimeUsernameProblemLanguageResultExecution timeMemory
1339600lucas110550Migrations (IOI25_migrations)C++20
23 / 100
28 ms452 KiB
// ------------------------------------------------------------
//  Dinosaur migration – research team (send_message) and Museum
// ------------------------------------------------------------

#include <vector>
#include <utility>   // std::pair
#include <algorithm> // std::max

// -----------------------------------------------------------------
//  Constants and global data that survive across calls of send_message
// -----------------------------------------------------------------
static const int _BLOCK = 100;          // block size for the encoding

// current test case size (0 means “no test case started yet”)
static int _curr_N = -1;

// depth[v] for the vertices that have already been visited
static std::vector<int> _depth;

// deepest distance seen so far and the *largest* vertex that attains it
static int _max_depth = -1;
static int _max_node  = -1;

int send_message(int N, int i, int Pi)
{
    // (re)initialise the data structures when we get a new test case
    if (N != _curr_N) {
        _curr_N   = N;
        _depth.assign(N, 0);   // depth[0] stays 0, others are filled later
        _max_depth = -1;
        _max_node  = -1;
    }

    // depth of the current vertex
    int d = _depth[Pi] + 1;
    _depth[i] = d;

    // keep the deepest vertex seen so far (largest index on ties)
    if (d > _max_depth || (d == _max_depth && i > _max_node)) {
        _max_depth = d;
        _max_node  = i;
    }

    // decide what (if anything) to send from site i
    if (i == N - 2) {                       // second‑last site – send block part
        int block = _max_node / _BLOCK;     // integer division, always >= 0
        return block + 1;                   // 1 … 100
    }
    else if (i == N - 1) {                  // last site – send remainder part
        int rem = _max_node % _BLOCK;       // remainder in [0, 99]
        return rem + 1;                     // 1 … 100
    }
    else {
        return 0;                           // no message
    }
}

std::pair<int,int> longest_path(std::vector<int> S)
{
    const int N = static_cast<int>(S.size());

    if (N == 1) {
        return {0, 0};
    }

    // The two last entries are the encoded answer.
    int block_val = S[N - 2];
    int rem_val   = S[N - 1];

    // Convert back to the original block index (0‑based) and remainder.
    // The Python code treats a value of 0 as “invalid” → map to 0.
    int block = (block_val > 0) ? (block_val - 1) : 0;   // 0 … 99
    int rem   = (rem_val   > 0) ? (rem_val   - 1) : 0;   // 0 … 99

    // Re‑assemble the index of the farthest vertex.
    // The Python code also clamps the value to the range [0, N‑1].
    int idx = block * _BLOCK + rem;

    if (idx < 0)            idx = 0;
    else if (idx >= N)      idx = N - 1;

    // Site 0 is always an endpoint of a diameter (as required by the
    // original research problem).  The second endpoint is `idx`.
    return {0, idx};
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...