Submission #1258151

#TimeUsernameProblemLanguageResultExecution timeMemory
1258151biankMigrations (IOI25_migrations)C++20
97.45 / 100
31 ms1212 KiB
#include "migrations.h" #include <bits/stdc++.h> using namespace std; #define forsn(i, s, n) for (int i = int(s); i < int(n); i++) #define forn(i, n) forsn(i, 0, n) #define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--) #define dforn(i, n) dforsn(i, 0, n) using vi = vector<int>; using ll = long long; using ii = pair<int, int>; #define fst first #define snd second #define sz(x) int(x.size()) #define all(x) begin(x), end(x) #define pb push_back #define eb emplace_back const int N = 10000, K = 15; int up[K][N], depth[N]; int lca(int u, int v) { if (depth[u] < depth[v]) swap(u, v); int diff = depth[u] - depth[v]; forn(i, K) if (diff >> i & 1) u = up[i][u]; if (u == v) return u; dforn(i, K) if (up[i][u] != up[i][v]) { u = up[i][u], v = up[i][v]; } assert(up[0][u] == up[0][v]); return up[0][u]; } int dist(int u, int v) { return depth[u] + depth[v] - 2 * depth[lca(u, v)]; } const int B[9] = {200, 36, 9, 1, 1, 1, 1, 1, 1}; const int T[9] = {1, 1, 1, 1, 2, 3, 2, 3, 4}; int D[9]; int u, v; vi candidatesU, candidatesV; int indice, value; void reduce(vi &c, int v, int l) { vi new_c; forn(i, sz(c)) { if (i / l == v) new_c.pb(c[i]); } c = new_c; } int send_message(int /*N*/, int i, int Pi) { if (i == 1) { depth[0] = 0; forn(j, K) up[j][0] = 0; u = 0, v = 0; candidatesU.pb(0), candidatesV.pb(0); D[8] = B[8]; dforn(j, 8) D[j] = D[j + 1] + B[j]; } up[0][i] = Pi, depth[i] = depth[Pi] + 1; forn(j, K - 1) up[j + 1][i] = up[j][up[j][i]]; if (dist(i, u) > dist(u, v)) v = i; else if (dist(i, v) > dist(u, v)) u = i; candidatesU.pb(i), candidatesV.pb(i); if (i < N - D[0]) return 0; forn(g, 9) { if (i == N - D[g]) { int idxU = 0, idxV = 0; while (candidatesU[idxU] != u) idxU++; while (candidatesV[idxV] != v) idxV++; int base = T[g] == 1 ? (int) sqrt(B[g] * 4) : 5; int lenU = (sz(candidatesU) + base - 1) / base; int lenV = (sz(candidatesV) + base - 1) / base; int sectionU = idxU / lenU; assert(sectionU < base); int sectionV = idxV / lenV; assert(sectionV < base); if (T[g] <= 2) reduce(candidatesU, sectionU, lenU); if (T[g] % 2 == 1) reduce(candidatesV, sectionV, lenV); indice = 0; if (T[g] == 1) { int number = sectionU * base + sectionV; indice = number / 4; assert(indice < B[g]); value = number % 4 + 1; } else if (T[g] == 2) value = sectionU; else if (T[g] == 3) value = sectionV; else { int idx = 0; forn(i, sz(candidatesU)) forn(j, sz(candidatesV)) { if (candidatesU[i] == candidatesV[j]) continue; if (candidatesU[i] == u && candidatesV[j] == v) value = idx; idx++; } } } } forn(g, 9) if (i == N - D[g] + indice) return value; return 0; } ii longest_path(vi S) { D[8] = B[8]; dforn(j, 8) D[j] = D[j + 1] + B[j]; vi candidatesU, candidatesV; forn(i, N) { candidatesU.pb(i), candidatesV.pb(i); forn(g, 9) if (i == N - D[g]) { int indice = -1, value = -1; forsn(j, i, i + B[g]) if (S[j] || (indice == -1 && j == i + B[g] - 1)) { indice = j - i; value = S[j]; } int base = T[g] == 1 ? (int) sqrt(B[g] * 4) : 5; int lenU = (sz(candidatesU) + base - 1) / base; int lenV = (sz(candidatesV) + base - 1) / base; int number = indice * 4 + (value - 1); int sectionU = T[g] == 1 ? number / base : value; int sectionV = T[g] == 1 ? number % base : value; if (T[g] <= 2) reduce(candidatesU, sectionU, lenU); if (T[g] % 2 == 1) reduce(candidatesV, sectionV, lenV); if (T[g] == 4) { int idx = 0; forn(i, sz(candidatesU)) forn(j, sz(candidatesV)) { if (candidatesU[i] == candidatesV[j]) continue; if (idx == value) return {candidatesU[i], candidatesV[j]}; idx++; } } } } assert(false); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...