제출 #1273673

#제출 시각아이디문제언어결과실행 시간메모리
1273673lucas110550이주 (IOI25_migrations)C++20
20 / 100
43 ms912 KiB
#include <bits/stdc++.h> using namespace std; const int LOG = 15; // 2^14 = 16384 > 10000 // ---------- global state for the incremental construction ---------- static int gN = -1; static vector<int> gDepth; static vector<array<int, LOG>> gUp; static int gA = 0, gB = 0, gD = 0; // current diameter endpoints and length static int gAprev = -1, gBprev = -1; // endpoints after processing N-2 // ---------- LCA utilities ---------- int lca(int u, int v) { if (gDepth[u] < gDepth[v]) swap(u, v); int diff = gDepth[u] - gDepth[v]; for (int k = LOG - 1; k >= 0; --k) if (diff & (1 << k)) u = gUp[u][k]; if (u == v) return u; for (int k = LOG - 1; k >= 0; --k) { if (gUp[u][k] != gUp[v][k]) { u = gUp[u][k]; v = gUp[v][k]; } } return gUp[u][0]; } int dist(int u, int v) { int w = lca(u, v); return gDepth[u] + gDepth[v] - 2 * gDepth[w]; } // ---------- send_message implementation ---------- int send_message(int N, int i, int Pi) { // (re)initialise for a new test case if (gN != N) { gN = N; gDepth.assign(N, 0); gUp.assign(N, array<int, LOG>()); for (int k = 0; k < LOG; ++k) gUp[0][k] = 0; gA = gB = 0; gD = 0; gAprev = gBprev = -1; } // set depth and binary lifting ancestors for node i gDepth[i] = gDepth[Pi] + 1; gUp[i][0] = Pi; for (int k = 1; k < LOG; ++k) gUp[i][k] = gUp[gUp[i][k - 1]][k - 1]; // update the diameter using the new node i int da = dist(i, gA); int db = dist(i, gB); if (da > gD) { gB = i; gD = da; } else if (db > gD) { gA = i; gD = db; } // node N-2: remember the current endpoints and send the first endpoint if (i == N - 2) { gAprev = gA; gBprev = gB; return gA + 1; // encode a+1 (always 1..10000) } // node N-1: we now know the final diameter, encode the second endpoint / flag if (i == N - 1) { bool unchanged = ( (gA == gAprev && gB == gBprev) || (gA == gBprev && gB == gAprev) ); if (unchanged) { // unchanged: send bprev+1 (<=10000) return gBprev + 1; } else if ( (gA == N - 1 && gB == gAprev) || (gB == N - 1 && gA == gAprev) ) { // new leaf paired with a_prev -> (N-1, a_prev) // encode by sending nothing return 0; } else { // new leaf paired with b_prev -> (N-1, b_prev) // encode as bprev + 10001 (range 10001..19999) return gBprev + 10001; } } // any other node: we do not send a message return 0; } // ---------- longest_path implementation ---------- pair<int, int> longest_path(vector<int> S) { int N = (int)S.size(); // S[0] is always 0 int a = S[N - 2] - 1; // first endpoint stored at N-2 int v = S[N - 1]; // second part / flag int u, w; if (v == 0) { // (N-1, a) u = a; w = N - 1; } else if (v <= 10000) { // unchanged case (a, b) u = a; w = v - 1; } else { // (N-1, b) u = N - 1; w = v - 10001; } return {u, w}; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...