Submission #1275574

#TimeUsernameProblemLanguageResultExecution timeMemory
1275574mehrzadMigrations (IOI25_migrations)C++17
0 / 100
31 ms1336 KiB
#include "migrations.h" #include <vector> #include <algorithm> #include <cmath> namespace { // These variables will persist across calls to send_message int N_val; // For LCA and distance calculation std::vector<int> parent; std::vector<int> depth; std::vector<std::vector<int>> up; int LOG_N; // For diameter tracking int endpoint1 = 0, endpoint2 = 0; // For communication protocol int start_messaging_idx; bool init_sent = false; bool second_endpoint_pending = false; int pending_value = 0; int first_msg_idx = -1; } // Helper function to calculate distance between two nodes using LCA int get_dist(int u, int v) { if (depth[u] < depth[v]) std::swap(u, v); for (int k = LOG_N - 1; k >= 0; --k) { if (depth[u] - (1 << k) >= depth[v]) { u = up[u][k]; } } if (u == v) { // This is a direct ancestor-descendant path, distance is difference in depth. // Re-calculating depth difference as u or v might have been swapped. return (depth[u] > depth[v] ? depth[u] : depth[v]) - (depth[u] < depth[v] ? depth[u] : depth[v]); } for (int k = LOG_N - 1; k >= 0; --k) { if (up[u][k] != up[v][k]) { u = up[u][k]; v = up[v][k]; } } int lca = parent[u]; return depth[u] + depth[v] - 2 * depth[lca]; } void initialize(int N) { N_val = N; parent.assign(N, -1); depth.assign(N, 0); LOG_N = 0; while ((1 << LOG_N) <= N) { LOG_N++; } up.assign(N, std::vector<int>(LOG_N, 0)); parent[0] = 0; for(int k=0; k<LOG_N; ++k) up[0][k] = 0; endpoint1 = 0; endpoint2 = 0; start_messaging_idx = std::max(1, N - 50); init_sent = false; second_endpoint_pending = false; pending_value = 0; first_msg_idx = -1; } int send_message(int N, int i, int Pi) { if (i == 1) { initialize(N); } // Update tree structure for LCA parent[i] = Pi; depth[i] = depth[Pi] + 1; up[i][0] = Pi; for (int k = 1; k < LOG_N; ++k) { up[i][k] = up[up[i][k-1]][k-1]; } // Update diameter endpoints int dist_e1_e2 = get_dist(endpoint1, endpoint2); int dist_i_e1 = get_dist(i, endpoint1); int dist_i_e2 = get_dist(i, endpoint2); bool diameter_changed = false; int other_endpoint = -1; if (dist_i_e1 > dist_e1_e2 && dist_i_e1 >= dist_i_e2) { other_endpoint = endpoint1; endpoint2 = i; diameter_changed = true; } else if (dist_i_e2 > dist_e1_e2 && dist_i_e2 > dist_i_e1) { other_endpoint = endpoint2; endpoint1 = i; diameter_changed = true; } if (i < start_messaging_idx) { return 0; } int message_to_send = 0; if (!init_sent) { if (diameter_changed) { message_to_send = other_endpoint + 1; } else { message_to_send = endpoint1 + 1; first_msg_idx = i; second_endpoint_pending = true; pending_value = endpoint2 + 1; } init_sent = true; } else if (second_endpoint_pending) { if (diameter_changed) { message_to_send = other_endpoint + 1; } else { message_to_send = pending_value; } second_endpoint_pending = false; } else { if (diameter_changed) { message_to_send = other_endpoint + 1; } } return message_to_send; } std::pair<int, int> longest_path(std::vector<int> S) { std::vector<std::pair<int, int>> msgs; for (size_t i = 0; i < S.size(); ++i) { if (S[i] != 0) { msgs.push_back({(int)i, S[i]}); } } if (msgs.empty()) { return {0, 0}; } if (msgs.size() == 1) { return {msgs[0].first, msgs[0].second - 1}; } if (msgs.size() == 2) { int i1 = msgs[0].first; int v1 = msgs[0].second; int i2 = msgs[1].first; int v2 = msgs[1].second; if (v2 == v1 || v2 - 1 == i1) { return {i2, v2 - 1}; } else { return {v1 - 1, v2 - 1}; } } return {msgs.back().first, msgs.back().second - 1}; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...