#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;
const int 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)];
}
vi perm[N], invPerm[N];
/*void generate_perms() {
srand(42);
vi p(5);
iota(all(p), 0);
forn(i, N) {
random_shuffle(all(p));
perm[i] = p;
vi inv_p(5);
forn(j, 5) inv_p[p[j]] = j;
invPerm[i] = inv_p;
}
}*/
int knownU, knownV;
int u, v;
int message;
vi pending;
int getOption() {
int idx = 0;
forn(i, sz(pending)) forsn(j, i + 1, sz(pending)) {
if (pending[i] == u && pending[j] == v) {
knownU = u, knownV = v;
return idx;
}
idx++;
}
forn(i, sz(pending)) {
if (pending[i] == u && knownV == v) {
knownU = u;
return idx;
}
idx++;
}
forn(i, sz(pending)) {
if (knownU == u && pending[i] == v) {
knownV = v;
return idx;
}
idx++;
}
return idx;
}
int send_message(int /*N*/, int i, int Pi) {
if (i == 1) {
//generate_perms();
depth[0] = 0;
forn(j, K) up[j][0] = 0;
u = 0, v = 0;
message = 0;
knownU = 0, knownV = 0;
}
pending.pb(i);
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, v) > dist(u, v)) u = i;
else if (dist(i, u) > dist(u, v)) v = i;
if (u != knownU && v != knownV && i <= N - 5 && u > v) swap(u, v);
if (i < N - 17) return 0;
if (i == N - 1) {
vector<ii> candidates = {
{knownU, N - 1},
{knownU, N - 2},
{N - 1, knownV},
{N - 1, N - 2},
{knownU, knownV}
};
int idx = 0;
while (candidates[idx] != ii{u, v}) idx++;
knownU = u, knownV = v;
return idx;
}
if (i == N - 2) {
vi candidates = {knownU, N - 2, N - 3, N - 4};
int idx = 0;
while (candidates[idx] != u) idx++;
knownU = candidates[idx];
return idx;
}
if (i == N - 5 || i == N - 17) {
message = getOption();
pending.clear();
}
int digit = message % 5;
message /= 5;
return digit;
}
ii getDiameter(int option, int U, int V) {
forn(i, sz(pending)) forsn(j, i + 1, sz(pending)) {
if (option-- == 0) return {pending[i], pending[j]};
}
forn(i, sz(pending)) {
if (option-- == 0) return {pending[i], V};
}
forn(i, sz(pending)) {
if (option-- == 0) return {U, pending[i]};
}
assert(option == 0);
return {U, V};
}
ii longest_path(vi S) {
int option = 0;
dforsn(i, N - 17, N - 5) option = 5 * option + S[i];
pending.clear();
forsn(i, 1, N - 17 + 1) pending.pb(i);
int U = 0, V = 0;
tie(U, V) = getDiameter(option, U, V);
option = 0;
pending.clear();
forsn(i, N - 17 + 1, N - 5 + 1) pending.pb(i);
dforsn(i, N - 5, N - 2) option = 5 * option + S[i];
tie(U, V) = getDiameter(option, U, V);
U = vi{U, N - 2, N - 3, N - 4}[S[N - 2]];
return vector<ii>{
{U, N - 1},
{U, N - 2},
{N - 1, V},
{N - 1, N - 2},
{U, V}
}[S[N - 1]];
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |