#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;
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++;
            if (T[g] == 1) {
                int base = (int) sqrt(B[g] * 4);
                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);
                vi newCandidatesU, newCandidatesV;
                forn(idx, sz(candidatesU)) {
                    if (idx / lenU == sectionU) newCandidatesU.pb(candidatesU[idx]);
                }
                forn(idx, sz(candidatesV)) {
                    if (idx / lenV == sectionV) newCandidatesV.pb(candidatesV[idx]);
                }
                candidatesU = newCandidatesU, candidatesV = newCandidatesV;
                int number = sectionU * base + sectionV;
                indice = number / 4;
                assert(indice < B[g]);
                value = number % 4 + 1;
            } else if (T[g] == 2) {
                int base = 5;
                int lenU = (sz(candidatesU) + base - 1) / base;
                int sectionU = idxU / lenU;
                assert(sectionU < base);
                indice = 0, value = sectionU;
                vi newCandidatesU;
                forn(idx, sz(candidatesU)) {
                    if (idx / lenU == sectionU) newCandidatesU.pb(candidatesU[idx]);
                }
                candidatesU = newCandidatesU;
            } else if (T[g] == 3) {
                int base = 5;
                int lenV = (sz(candidatesV) + base - 1) / base;
                int sectionV = idxV / lenV;
                assert(sectionV < base);
                indice = 0, value = sectionV;
                vi newCandidatesV;
                forn(idx, sz(candidatesV)) {
                    if (idx / lenV == sectionV) newCandidatesV.pb(candidatesV[idx]);
                }
                candidatesV = newCandidatesV;
            } else {
                int idx = 0;
                indice = 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];
            }
            if (T[g] == 1) {
                int number = indice * 4 + (value - 1);
                int base = (int) sqrt(B[g] * 4);
                int lenU = (sz(candidatesU) + base - 1) / base;
                int lenV = (sz(candidatesV) + base - 1) / base;
                int sectionU = number / base;
                int sectionV = number % base;
                vi newCandidatesU, newCandidatesV;
                forn(idx, sz(candidatesU)) {
                    if (idx / lenU == sectionU) newCandidatesU.pb(candidatesU[idx]);
                }
                forn(idx, sz(candidatesV)) {
                    if (idx / lenV == sectionV) newCandidatesV.pb(candidatesV[idx]);
                }
                candidatesU = newCandidatesU, candidatesV = newCandidatesV;
            } else if (T[g] == 2) {
                int base = 5;
                int lenU = (sz(candidatesU) + base - 1) / base;
                vi newCandidatesU;
                forn(idx, sz(candidatesU)) {
                    if (idx / lenU == value) newCandidatesU.pb(candidatesU[idx]);
                }
                candidatesU = newCandidatesU;
            } else if (T[g] == 3) {
                int base = 5;
                int lenV = (sz(candidatesV) + base - 1) / base;
                vi newCandidatesV;
                forn(idx, sz(candidatesV)) {
                    if (idx / lenV == value) newCandidatesV.pb(candidatesV[idx]);
                }
                candidatesV = newCandidatesV;
            } else if (T[g] == 4) {
                int idx = 0;
                forn(i, sz(candidatesU)) forn(j, sz(candidatesV)) {
                    if (candidatesU[i] == candidatesV[i]) continue;
                    if (idx == value) return {candidatesU[i], candidatesV[i]};
                    idx++;
                }
            }
        }
    }
    assert(false);
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |