Submission #1258257

#TimeUsernameProblemLanguageResultExecution timeMemory
1258257biankMigrations (IOI25_migrations)C++20
30 / 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 MOVES = 8; const int B[MOVES] = {140, 20, 6, 2, 2, 1, 1, 1}; const int T[MOVES] = {-1, 1, 1, 1, 1, 2, 3, 4}; int D[MOVES]; 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 getBase(int g) { int base = T[g] == 1 ? (int) sqrt(B[g] * 4 + 1) : 5; if (T[g] == -1) { base = 1; while ((base + 2) * (base + 1) / 2 <= B[g] * 4) base++; } return base; } 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[MOVES - 1] = B[MOVES - 1]; dforn(j, MOVES - 1) 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; if (i <= N - D[0] && u > v) swap(u, v); forn(g, MOVES) if (i == N - D[g]) { int idxU = 0, idxV = 0; while (candidatesU[idxU] != u) idxU++; while (candidatesV[idxV] != v) idxV++; int base = getBase(g); 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 != 0) reduce(candidatesV, sectionV, lenV); if (T[g] == -1) { assert(sectionU <= sectionV); assert(base * (base + 1) / 2 <= B[g] * 4 + 1); int number = sectionV * (sectionV + 1) / 2 + sectionU - 1; indice = number == -1 ? 0 : number / 4; assert(indice < B[g]); value = number % 4 + 1; continue; } if (T[g] == 1) { int number = sectionU * base + sectionV - 1; indice = number == -1 ? 0 : 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, MOVES) if (i == N - D[g] + indice) return value; return 0; } ii longest_path(vi S) { D[MOVES - 1] = B[MOVES - 1]; dforn(j, MOVES - 1) D[j] = D[j + 1] + B[j]; vi candidatesU, candidatesV; forn(i, N) { candidatesU.pb(i), candidatesV.pb(i); forn(g, MOVES) 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 = getBase(g); int lenU = (sz(candidatesU) + base - 1) / base; int lenV = (sz(candidatesV) + base - 1) / base; int number = value == 0 ? 0 : indice * 4 + (value - 1) + 1; int sectionU = T[g] == 1 ? number / base : value; int sectionV = T[g] == 1 ? number % base : value; if (T[g] == -1) { sectionV = 0; while ((sectionV + 1) * (sectionV + 2) / 2 <= number) sectionV++; sectionU = number - sectionV * (sectionV + 1) / 2; } if (T[g] <= 2) reduce(candidatesU, sectionU, lenU); if (T[g] % 2 != 0) 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...