Submission #1368190

#TimeUsernameProblemLanguageResultExecution timeMemory
1368190llmMigrations (IOI25_migrations)C++20
0 / 100
22 ms1108 KiB
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// Sender's global state
static int depth_arr[100005];
static int up[100005][17];
static int U_curr = 0, V_curr = 0;
static int max_dist = 0;
static int msg_count = 0;
static bool is_simple_path = true;

int get_lca(int u, int v) {
    if (depth_arr[u] < depth_arr[v]) swap(u, v);
    for (int j = 16; j >= 0; --j) {
        if (depth_arr[u] - (1 << j) >= depth_arr[v]) u = up[u][j];
    }
    if (u == v) return u;
    for (int j = 16; j >= 0; --j) {
        if (up[u][j] != up[v][j]) {
            u = up[u][j];
            v = up[v][j];
        }
    }
    return up[u][0];
}

int get_dist(int u, int v) {
    return depth_arr[u] + depth_arr[v] - 2 * depth_arr[get_lca(u, v)];
}

int send_message(int N, int i, int Pi) {
    if (i == 1) {
        U_curr = 0; V_curr = 0; max_dist = 0; msg_count = 0;
        is_simple_path = true;
        depth_arr[0] = 0;
        for (int j = 0; j <= 16; ++j) up[0][j] = 0;
    }

    if (Pi != i - 1) is_simple_path = false;

    depth_arr[i] = depth_arr[Pi] + 1;
    up[i][0] = Pi;
    for (int j = 1; j <= 16; ++j) {
        up[i][j] = up[up[i][j - 1]][j - 1];
    }

    int dU = get_dist(i, U_curr);
    int dV = get_dist(i, V_curr);

    // If it's a simple path, we remain perfectly silent (0 messages)
    if (is_simple_path) return 0;

    bool changed = false;
    int previous_U = U_curr, previous_V = V_curr;

    if (dU > max_dist || dV > max_dist) {
        if (dU >= dV) { V_curr = i; max_dist = dU; } 
        else { U_curr = i; max_dist = dV; }
        changed = true;
    }

    // We only send a message if the diameter changed AND we have quota
    // We encode the OTHER endpoint so the Museum can pair it with `i`
    if (changed && msg_count < 48) {
        msg_count++;
        // If U was replaced by i, we send V_curr + 1. If V was replaced, we send U_curr + 1
        return (dU >= dV) ? (previous_U + 1) : (previous_V + 1);
    }
    
    return 0;
}

std::pair<int, int> longest_path(std::vector<int> S) {
    int N = S.size();
    int final_U = 0, final_V = 0;
    bool received_any = false;
    
    for (int i = 1; i < N; ++i) {
        if (S[i] > 0) {
            received_any = true;
            final_V = i;          // The index where the diameter changed
            final_U = S[i] - 1;   // The other endpoint encoded in the value
        }
    }
    
    // If the sender was perfectly silent, it was an adversarial simple path graph
    if (!received_any) {
        return {0, N - 1};
    }
    
    // Otherwise, we safely return the last recorded endpoints
    return {final_U, final_V};
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...