Submission #1275584

#TimeUsernameProblemLanguageResultExecution timeMemory
1275584mehrzad이주 (IOI25_migrations)C++17
28.09 / 100
31 ms1168 KiB
#include "migrations.h" #include <vector> #include <array> #include <utility> #include <algorithm> using namespace std; // --------------------- Internal state for run #1 (send_message) --------------------- namespace { bool inited = false; int Nglob = 0, LOGv = 0; int startIdx = 1; // start of the last-50 suffix // Lifting tables vector<int> depth; vector< vector<int> > up; // up[v][k], k in [0..LOGv-1] // Online diameter int A = 0, B = 0, D = 0; // endpoints and length // Suffix init bookkeeping bool sentInitA = false; bool sentInitB = false; inline void reset_test(int N) { inited = true; Nglob = N; LOGv = 0; while ((1 << LOGv) <= (Nglob > 0 ? Nglob : 1)) ++LOGv; depth.assign(Nglob, 0); up.assign(Nglob, vector<int>(LOGv, 0)); for (int k = 0; k < LOGv; ++k) up[0][k] = 0; A = B = 0; D = 0; int K = (Nglob >= 2 ? 50 : max(1, Nglob - 1)); startIdx = max(1, Nglob - K); sentInitA = false; sentInitB = false; } inline int lca(int u, int v) { if (depth[u] < depth[v]) swap(u, v); int diff = depth[u] - depth[v]; for (int k = 0; k < LOGv; ++k) if (diff & (1 << k)) u = up[u][k]; if (u == v) return u; for (int k = LOGv - 1; k >= 0; --k) { if (up[u][k] != up[v][k]) { u = up[u][k]; v = up[v][k]; } } return up[u][0]; } inline int dist(int u, int v) { int w = lca(u, v); return depth[u] + depth[v] - 2 * depth[w]; } } int send_message(int N, int i, int Pi) { // New test case begins at i == 1 (per problem statement). if (!inited || i == 1) reset_test(N); // add node i to lifting depth[i] = depth[Pi] + 1; up[i][0] = Pi; for (int k = 1; k < LOGv; ++k) up[i][k] = up[ up[i][k-1] ][k-1]; // online diameter update int dA = dist(i, A); int dB = dist(i, B); bool changed = false; int other = -1; if (dA > D) { changed = true; other = A; B = i; D = dA; } else if (dB > D) { changed = true; other = B; A = i; D = dB; } // default: no message int out = 0; // Communicate only in the last-50 suffix. if (i >= startIdx) { if (i == startIdx && !sentInitA) { // First deterministic init: A out = A + 1; // in [1..N] ≤ 10000 sentInitA = true; } else if (i == startIdx + 1 && !sentInitB) { // Second deterministic init: B out = B + 1; sentInitB = true; } else if (changed) { // Any real change inside suffix: send other endpoint out = other + 1; } // else: silent } // 0 or [1..20000] is allowed; here values are ≤ 10000 by construction. return out; } // --------------------- Run #2 (Museum) --------------------- std::pair<int,int> longest_path(std::vector<int> S) { int N = (int)S.size(); if (N <= 1) return {0, 0}; int K = (N >= 2 ? 50 : max(1, N - 1)); int startIdxLocal = max(1, N - K); // Find the last message sent at or after startIdxLocal+2 (i.e., any "change" after the two inits) int lastIdx = -1; for (int i = N - 1; i >= startIdxLocal + 2; --i) { if (S[i] != 0) { lastIdx = i; break; } } if (lastIdx != -1) { // This is a real change message: (lastIdx, S[lastIdx]-1) return { lastIdx, S[lastIdx] - 1 }; } // Otherwise, no changes occurred in the suffix after the two inits. // Use the two deterministic init messages placed at startIdxLocal and startIdxLocal+1. // (They are guaranteed to be sent by the team code.) int u = (S[startIdxLocal] > 0 ? S[startIdxLocal] - 1 : 0); int v = (S[startIdxLocal + 1] > 0 ? S[startIdxLocal + 1] - 1 : 0); return { u, v }; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...